From 767c79beaee716fec8b79576ed0445d341ff6a96 Mon Sep 17 00:00:00 2001 From: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com> Date: Tue, 18 Nov 2025 04:13:38 +0000 Subject: [PATCH] fix `last` on iterators with dup values --- heed/src/databases/database.rs | 1 + heed/src/iterator/iter.rs | 48 +++------------------------------- heed/src/iterator/mod.rs | 6 ++--- 3 files changed, 8 insertions(+), 47 deletions(-) diff --git a/heed/src/databases/database.rs b/heed/src/databases/database.rs index 46ccc902..0a79cac8 100644 --- a/heed/src/databases/database.rs +++ b/heed/src/databases/database.rs @@ -434,6 +434,7 @@ impl Database { /// drop(iter); /// /// let mut iter = db.get_duplicates(&wtxn, &68)?.expect("the key exists"); + /// assert_eq!(iter.next().transpose()?, Some((68, 120))); /// assert_eq!(iter.last().transpose()?, Some((68, 123))); /// /// wtxn.commit()?; diff --git a/heed/src/iterator/iter.rs b/heed/src/iterator/iter.rs index 2f85fca5..17e3a97d 100644 --- a/heed/src/iterator/iter.rs +++ b/heed/src/iterator/iter.rs @@ -179,17 +179,7 @@ where } fn last(mut self) -> Option { - let result = if self.move_on_first { - self.cursor.move_on_last(IM::MOVE_OPERATION) - } else { - match (self.cursor.current(), self.cursor.move_on_last(IM::MOVE_OPERATION)) { - (Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => { - Ok(Some((key, data))) - } - (Ok(_), Ok(_)) => Ok(None), - (Err(e), _) | (_, Err(e)) => Err(e), - } - }; + let result = self.cursor.move_on_last(IM::MOVE_OPERATION); match result { Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) { @@ -408,17 +398,7 @@ where } fn last(mut self) -> Option { - let result = if self.move_on_first { - self.cursor.move_on_last(IM::MOVE_OPERATION) - } else { - match (self.cursor.current(), self.cursor.move_on_last(IM::MOVE_OPERATION)) { - (Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => { - Ok(Some((key, data))) - } - (Ok(_), Ok(_)) => Ok(None), - (Err(e), _) | (_, Err(e)) => Err(e), - } - }; + let result = self.cursor.move_on_last(IM::MOVE_OPERATION); match result { Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) { @@ -525,17 +505,7 @@ where } fn last(mut self) -> Option { - let result = if self.move_on_last { - self.cursor.move_on_first(IM::MOVE_OPERATION) - } else { - match (self.cursor.current(), self.cursor.move_on_first(IM::MOVE_OPERATION)) { - (Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => { - Ok(Some((key, data))) - } - (Ok(_), Ok(_)) => Ok(None), - (Err(e), _) | (_, Err(e)) => Err(e), - } - }; + let result = self.cursor.move_on_first(IM::MOVE_OPERATION); match result { Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) { @@ -756,17 +726,7 @@ where } fn last(mut self) -> Option { - let result = if self.move_on_last { - self.cursor.move_on_first(IM::MOVE_OPERATION) - } else { - match (self.cursor.current(), self.cursor.move_on_first(IM::MOVE_OPERATION)) { - (Ok(Some((ckey, _))), Ok(Some((key, data)))) if ckey != key => { - Ok(Some((key, data))) - } - (Ok(_), Ok(_)) => Ok(None), - (Err(e), _) | (_, Err(e)) => Err(e), - } - }; + let result = self.cursor.move_on_first(IM::MOVE_OPERATION); match result { Ok(Some((key, data))) => match (KC::bytes_decode(key), DC::bytes_decode(data)) { diff --git a/heed/src/iterator/mod.rs b/heed/src/iterator/mod.rs index 9622fbe4..db118a98 100644 --- a/heed/src/iterator/mod.rs +++ b/heed/src/iterator/mod.rs @@ -227,7 +227,7 @@ mod tests { assert_eq!(iter.next().transpose().unwrap(), Some((2, ()))); assert_eq!(iter.next().transpose().unwrap(), Some((3, ()))); assert_eq!(iter.next().transpose().unwrap(), Some((4, ()))); - assert_eq!(iter.last().transpose().unwrap(), None); + assert_eq!(iter.last().transpose().unwrap(), Some((4, ()))); let mut iter = db.iter(&wtxn).unwrap(); assert_eq!(iter.next().transpose().unwrap(), Some((1, ()))); @@ -235,7 +235,7 @@ mod tests { assert_eq!(iter.next().transpose().unwrap(), Some((3, ()))); assert_eq!(iter.next().transpose().unwrap(), Some((4, ()))); assert_eq!(iter.next().transpose().unwrap(), None); - assert_eq!(iter.last().transpose().unwrap(), None); + assert_eq!(iter.last().transpose().unwrap(), Some((4, ()))); wtxn.abort(); @@ -249,7 +249,7 @@ mod tests { let mut iter = db.iter(&wtxn).unwrap(); assert_eq!(iter.next().transpose().unwrap(), Some((1, ()))); - assert_eq!(iter.last().transpose().unwrap(), None); + assert_eq!(iter.last().transpose().unwrap(), Some((1, ()))); wtxn.abort(); }