diff options
| author | metamuffin <metamuffin@disroot.org> | 2025-12-19 21:52:59 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2025-12-19 21:52:59 +0100 |
| commit | eac0de36221440571fe686074b04b71bf98cf727 (patch) | |
| tree | 76bad4c937e203bc13b6adcced9ed0b41432c2ae /database/src/iterator.rs | |
| parent | da985cc06e4caa7501222dbf54f212536fd42b0c (diff) | |
| download | jellything-eac0de36221440571fe686074b04b71bf98cf727.tar jellything-eac0de36221440571fe686074b04b71bf98cf727.tar.bz2 jellything-eac0de36221440571fe686074b04b71bf98cf727.tar.zst | |
things
Diffstat (limited to 'database/src/iterator.rs')
| -rw-r--r-- | database/src/iterator.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/database/src/iterator.rs b/database/src/iterator.rs new file mode 100644 index 0000000..2db349b --- /dev/null +++ b/database/src/iterator.rs @@ -0,0 +1,70 @@ +/* + This file is part of jellything (https://codeberg.org/metamuffin/jellything) + which is licensed under the GNU Affero General Public License (version 3); see /COPYING. + Copyright (C) 2025 metamuffin <metamuffin.org> +*/ + +use crate::backends::ReadTransaction; +use anyhow::Result; +use std::{borrow::Cow, ops::Range}; + +pub struct PrefixIterator<'a> { + db: &'a dyn ReadTransaction, + prefix: &'a [u8], + cursor: Cow<'a, [u8]>, +} +impl Iterator for PrefixIterator<'_> { + type Item = Result<Vec<u8>>; + fn next(&mut self) -> Option<Self::Item> { + match self.db.next(&self.cursor) { + Err(e) => Some(Err(e)), + Ok(None) => None, + Ok(Some(next)) => { + if next.starts_with(self.prefix) { + self.cursor = next.clone().into(); + Some(Ok(next)) + } else { + None + } + } + } + } +} + +pub struct RangeIterator<'a> { + db: &'a dyn ReadTransaction, + range: Range<Cow<'a, [u8]>>, +} +impl Iterator for RangeIterator<'_> { + type Item = Result<Vec<u8>>; + fn next(&mut self) -> Option<Self::Item> { + match self.db.next(&self.range.start) { + Err(e) => Some(Err(e)), + Ok(None) => None, + Ok(Some(next)) => { + if next.as_slice() < self.range.end.as_ref() { + self.range.start = next.clone().into(); + Some(Ok(next)) + } else { + None + } + } + } + } +} +impl DoubleEndedIterator for RangeIterator<'_> { + fn next_back(&mut self) -> Option<Self::Item> { + match self.db.prev(&self.range.end) { + Err(e) => Some(Err(e)), + Ok(None) => None, + Ok(Some(prev)) => { + if prev.as_slice() >= self.range.start.as_ref() { + self.range.end = prev.clone().into(); + Some(Ok(prev)) + } else { + None + } + } + } + } +} |