Mercurial > lbo > hg > leveldb-rs
changeset 4:6cc4b1f36f81
Implement SkipMapIterator
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Thu, 09 Jun 2016 06:22:29 +0000 |
parents | cd0da27876f0 |
children | 648f5eaff65b |
files | src/skipmap.rs |
diffstat | 1 files changed, 49 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/skipmap.rs Thu Jun 09 05:56:43 2016 +0000 +++ b/src/skipmap.rs Thu Jun 09 06:22:29 2016 +0000 @@ -2,7 +2,8 @@ use rand::{Rng, SeedableRng, StdRng}; use std::cmp::Ordering; - +use std::default::Default; +use std::marker; use std::mem::{replace, transmute_copy}; const MAX_HEIGHT: usize = 12; @@ -175,6 +176,12 @@ self.len += 1; } + fn iter<'a>(&'a self) -> SkipMapIter<'a, C> { + SkipMapIter { + _map: Default::default(), + current: unsafe { transmute_copy(&self.head.as_ref()) }, + } + } // Runs through the skipmap and prints everything including addresses fn dbg_print(&self) { @@ -196,6 +203,25 @@ } } +pub struct SkipMapIter<'a, C: Comparator + 'a> { + _map: marker::PhantomData<&'a SkipMap<C>>, + current: *const Node, +} + +impl<'a, C: Comparator + 'a> Iterator for SkipMapIter<'a, C> { + type Item = (&'a Vec<u8>, &'a Vec<u8>); + + fn next(&mut self) -> Option<Self::Item> { + // we first go to the next element, then return that -- in order to skip the head node + unsafe { + (*self.current).next.as_ref().map(|next| { + self.current = transmute_copy(&next.as_ref()); + (&(*self.current).key, &(*self.current).value) + }) + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -238,4 +264,26 @@ assert!(!skm.contains(&"aaa".as_bytes().to_vec())); assert!(!skm.contains(&"456".as_bytes().to_vec())); } + + #[test] + fn test_iterator_0() { + let skm = SkipMap::new(); + let mut i = 0; + for (_, _) in skm.iter() { + i += 1; + } + assert_eq!(i, 0); + } + + #[test] + fn test_iterator() { + let skm = make_skipmap(); + let mut i = 0; + for (k, v) in skm.iter() { + assert!(!k.is_empty()); + assert!(!v.is_empty()); + i += 1; + } + assert_eq!(i, 26); + } }