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);
+    }
 }