aboutsummaryrefslogtreecommitdiff
path: root/common/object
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-01-14 20:28:54 +0100
committermetamuffin <metamuffin@disroot.org>2026-01-14 20:28:54 +0100
commitabf25f340c11111369b69c13c34d8fed9d4f0da8 (patch)
tree1e913a4affe3303a17a222c8215a51424d3b71b6 /common/object
parentb5ff460e938779be4eeab292c2cc1d436b93c137 (diff)
downloadjellything-abf25f340c11111369b69c13c34d8fed9d4f0da8.tar
jellything-abf25f340c11111369b69c13c34d8fed9d4f0da8.tar.bz2
jellything-abf25f340c11111369b69c13c34d8fed9d4f0da8.tar.zst
db binning and sorts
Diffstat (limited to 'common/object')
-rw-r--r--common/object/src/lib.rs27
-rw-r--r--common/object/src/path.rs38
2 files changed, 52 insertions, 13 deletions
diff --git a/common/object/src/lib.rs b/common/object/src/lib.rs
index ea64fd4..59a758f 100644
--- a/common/object/src/lib.rs
+++ b/common/object/src/lib.rs
@@ -7,6 +7,7 @@
mod buffer;
pub mod inspect;
+pub mod path;
mod registry;
#[cfg(test)]
mod tests;
@@ -57,7 +58,7 @@ impl<'a> Object<'a> {
.map(|&v| v >> 2)
.unwrap_or(self.values.len() as u32) as usize
}
- fn get_aligned(&self, index: usize) -> Option<&[u32]> {
+ fn get_aligned(&self, index: usize) -> Option<&'a [u32]> {
let start_raw = self.offsets[index];
let end_raw = self
.offsets
@@ -70,7 +71,7 @@ impl<'a> Object<'a> {
Some(&self.values[start as usize..end as usize])
}
- fn get_unaligned(&self, index: usize) -> Option<&[u8]> {
+ fn get_unaligned(&self, index: usize) -> Option<&'a [u8]> {
let start_raw = self.offsets[index];
let end_raw = self
.offsets
@@ -86,32 +87,32 @@ impl<'a> Object<'a> {
Some(&values_u8[start as usize..end as usize])
}
#[inline]
- pub fn get_typed<'b: 'a, T: Value<'b>>(&'b self, index: usize) -> Option<T> {
+ pub fn get_typed<T: Value<'a>>(&self, index: usize) -> Option<T> {
if T::ALIGNED {
T::load_aligned(self.get_aligned(index)?)
} else {
T::load_unaligned(self.get_unaligned(index)?)
}
}
- pub fn get<'b: 'a, T: Value<'b>>(&'b self, tag: TypedTag<T>) -> Option<T> {
+ pub fn get<T: Value<'a>>(&self, tag: TypedTag<T>) -> Option<T> {
self.get_typed(self.find_field(tag.0)?)
}
- pub fn keys<'b: 'a>(&'b self) -> KeysIter<'b> {
+ pub fn keys(&self) -> KeysIter<'a> {
KeysIter {
- object: self,
+ object: *self,
index: 0,
}
}
- pub fn entries<'b: 'a, T>(&'b self) -> EntriesIter<'b, T> {
+ pub fn entries<T>(&self) -> EntriesIter<'a, T> {
EntriesIter {
- object: self,
+ object: *self,
index: 0,
ty: PhantomData,
}
}
- pub fn iter<'b: 'a, T>(&'b self, tag: TypedTag<T>) -> FieldIter<'b, T> {
+ pub fn iter<T>(&self, tag: TypedTag<T>) -> FieldIter<'a, T> {
FieldIter {
- object: self,
+ object: *self,
index: self.tags.partition_point(|&x| x < tag.0.0),
tag: tag.0.0,
ty: PhantomData,
@@ -171,7 +172,7 @@ impl<'a> Object<'a> {
}
pub struct KeysIter<'a> {
- object: &'a Object<'a>,
+ object: Object<'a>,
index: usize,
}
impl Iterator for KeysIter<'_> {
@@ -187,7 +188,7 @@ impl Iterator for KeysIter<'_> {
}
pub struct EntriesIter<'a, T> {
- object: &'a Object<'a>,
+ object: Object<'a>,
index: usize,
ty: PhantomData<T>,
}
@@ -206,7 +207,7 @@ impl<'a, T: Value<'a>> Iterator for EntriesIter<'a, T> {
}
pub struct FieldIter<'a, T> {
- object: &'a Object<'a>,
+ object: Object<'a>,
index: usize,
tag: u32,
ty: PhantomData<T>,
diff --git a/common/object/src/path.rs b/common/object/src/path.rs
new file mode 100644
index 0000000..7db8798
--- /dev/null
+++ b/common/object/src/path.rs
@@ -0,0 +1,38 @@
+/*
+ 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) 2026 metamuffin <metamuffin.org>
+*/
+
+use crate::{Object, Tag, TypedTag};
+use std::marker::PhantomData;
+
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Path(pub Vec<Tag>);
+
+impl Path {
+ pub fn get_matching_value<'a>(&self, ob: Object<'a>) -> Option<&'a [u8]> {
+ fn recurse<'a>(ob: Object<'a>, path: &[Tag]) -> Option<&'a [u8]> {
+ if path.len() > 1 {
+ recurse(ob.get(TypedTag(path[0], PhantomData))?, path)
+ } else {
+ ob.get(TypedTag(path[0], PhantomData))
+ }
+ }
+ recurse(ob, &self.0)
+ }
+ pub fn get_matching_values<'a>(&self, ob: Object<'a>) -> Vec<&'a [u8]> {
+ fn recurse<'a>(ob: Object<'a>, out: &mut Vec<&'a [u8]>, path: &[Tag]) {
+ if path.len() > 1 {
+ for nested in ob.iter(TypedTag(path[0], PhantomData::<Object>)) {
+ recurse(nested, out, &path[1..]);
+ }
+ } else {
+ out.extend(ob.iter(TypedTag(path[0], PhantomData::<&[u8]>)));
+ }
+ }
+ let mut out = Vec::new();
+ recurse(ob, &mut out, &self.0);
+ out
+ }
+}