diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-01-11 02:51:24 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-01-11 02:51:24 +0100 |
| commit | 72a718fffb236c4b157e4d62c2e486ca7b326a26 (patch) | |
| tree | 17acd02fcd88dca48ce92e94d950a413d1cc8340 | |
| parent | 095d4234558c39f28ddc777f123a15e410a74c14 (diff) | |
| download | jellything-72a718fffb236c4b157e4d62c2e486ca7b326a26.tar jellything-72a718fffb236c4b157e4d62c2e486ca7b326a26.tar.bz2 jellything-72a718fffb236c4b157e4d62c2e486ca7b326a26.tar.zst | |
things
| -rw-r--r-- | common/object/src/lib.rs | 39 | ||||
| -rw-r--r-- | database/src/indices/mod.rs | 6 | ||||
| -rw-r--r-- | database/src/indices/rating.rs (renamed from database/src/indices/order.rs) | 24 | ||||
| -rw-r--r-- | database/src/indices/reference.rs (renamed from database/src/indices/key.rs) | 65 | ||||
| -rw-r--r-- | database/src/lib.rs | 16 |
5 files changed, 98 insertions, 52 deletions
diff --git a/common/object/src/lib.rs b/common/object/src/lib.rs index bb21942..7c97bee 100644 --- a/common/object/src/lib.rs +++ b/common/object/src/lib.rs @@ -12,14 +12,17 @@ mod registry; mod tests; mod value; pub use buffer::*; +use bytemuck::NoUninit; pub use registry::*; pub use value::*; use std::marker::PhantomData; #[repr(transparent)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(NoUninit, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct Tag(pub u32); + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct TypedTag<T>(pub Tag, pub PhantomData<T>); #[derive(Debug, Clone, Copy)] @@ -94,12 +97,19 @@ impl<'a> Object<'a> { pub fn get<'b: 'a, T: Value<'b>>(&'b self, tag: TypedTag<T>) -> Option<T> { self.get_typed(self.find_field(tag.0)?) } - pub fn keys<'b: 'a>(&'b self) -> ObjectIter<'b> { - ObjectIter { + pub fn keys<'b: 'a>(&'b self) -> KeysIter<'b> { + KeysIter { object: self, index: 0, } } + pub fn entries<'b: 'a, T>(&'b self) -> EntriesIter<'b, T> { + EntriesIter { + object: self, + index: 0, + ty: PhantomData, + } + } pub fn iter<'b: 'a, T>(&'b self, tag: TypedTag<T>) -> FieldIter<'b, T> { FieldIter { object: self, @@ -161,11 +171,11 @@ impl<'a> Object<'a> { } } -pub struct ObjectIter<'a> { +pub struct KeysIter<'a> { object: &'a Object<'a>, index: usize, } -impl Iterator for ObjectIter<'_> { +impl Iterator for KeysIter<'_> { type Item = Tag; fn next(&mut self) -> Option<Self::Item> { if self.index >= self.object.tags.len() { @@ -177,6 +187,25 @@ impl Iterator for ObjectIter<'_> { } } +pub struct EntriesIter<'a, T> { + object: &'a Object<'a>, + index: usize, + ty: PhantomData<T>, +} +impl<'a, T: Value<'a>> Iterator for EntriesIter<'a, T> { + type Item = (Tag, T); + fn next(&mut self) -> Option<Self::Item> { + if self.index >= self.object.tags.len() { + return None; + } else { + let value = self.object.get_typed(self.index)?; //? This ends the iterator early if there is any invalid field + let tag = self.object.tags[self.index]; + self.index += 1; + Some((Tag(tag), value)) + } + } +} + pub struct FieldIter<'a, T> { object: &'a Object<'a>, index: usize, diff --git a/database/src/indices/mod.rs b/database/src/indices/mod.rs index ad3d00f..2d8642a 100644 --- a/database/src/indices/mod.rs +++ b/database/src/indices/mod.rs @@ -8,14 +8,14 @@ use crate::{backends::WriteTransaction, table::RowNum}; use anyhow::Result; use jellycommon::jellyobject::Object; -pub mod key; -pub mod order; +pub mod reference; +pub mod rating; pub trait Index { fn add(&self, db: &mut dyn WriteTransaction, row: RowNum, val: Object) -> Result<()>; fn remove(&self, db: &mut dyn WriteTransaction, row: RowNum, val: Object) -> Result<()>; fn compare(&self, before: Object, after: Object) -> bool { let _ = (before, after); - true + false } } diff --git a/database/src/indices/order.rs b/database/src/indices/rating.rs index 911ec37..003d327 100644 --- a/database/src/indices/order.rs +++ b/database/src/indices/rating.rs @@ -10,32 +10,32 @@ use crate::{ table::{RowNum, TableNum}, }; use anyhow::Result; -use bytemuck::{NoUninit, bytes_of}; -use jellycommon::jellyobject::{Object, Tag}; +use bytemuck::NoUninit; +use jellycommon::jellyobject::{Object, Tag, TypedTag}; #[derive(Clone)] -pub struct OrderIndex { +pub struct RatingIndex { id: TableNum, - key: Vec<Tag>, + tag: TypedTag<Object<'static>>, } #[repr(C)] #[derive(NoUninit, Clone, Copy)] -struct Key(TableNum, [u8; 8], RowNum); +struct Key(TableNum, Tag, u32, u64, RowNum); -impl OrderIndex { - pub fn new(id: TableNum, value: fn(Object) -> [u8; 8]) -> Self { - Self { id, value } +impl RatingIndex { + pub fn new(id: TableNum, tag: TypedTag<Object<'static>>) -> Self { + Self { id, tag } } } -impl Index for OrderIndex { +impl Index for RatingIndex { fn add(&self, db: &mut dyn WriteTransaction, id: RowNum, val: Object) -> Result<()> { - db.set(bytes_of(&Key(self.id, (self.value)(val), id)), &[]) + todo!() } fn remove(&self, db: &mut dyn WriteTransaction, id: RowNum, val: Object) -> Result<()> { - db.del(bytes_of(&Key(self.id, (self.value)(val), id))) + todo!() } fn compare(&self, before: Object, after: Object) -> bool { - (self.value)(before) == (self.value)(after) + todo!() } } diff --git a/database/src/indices/key.rs b/database/src/indices/reference.rs index 2790220..66efa24 100644 --- a/database/src/indices/key.rs +++ b/database/src/indices/reference.rs @@ -11,58 +11,61 @@ use crate::{ table::{RowNum, TableNum}, }; use anyhow::Result; -use jellycommon::jellyobject::{Object, Tag}; +use bytemuck::{NoUninit, bytes_of}; +use jellycommon::jellyobject::{Object, TypedTag}; -pub struct KeyIndex { +pub struct ReferenceIndex { id: TableNum, - key: Vec<Tag>, + tag: TypedTag<RowNum>, } -impl KeyIndex { - pub fn new(id: TableNum, key: Vec<Tag>) -> Self { - Self { id, key } - } - pub fn key(&self, id: RowNum, key: &[u8]) -> Vec<u8> { - let mut v = Vec::new(); - v.extend(self.id.to_be_bytes()); - v.extend(key); - v.extend(id.to_be_bytes()); - v +#[repr(C)] +#[derive(NoUninit, Clone, Copy)] +pub struct Key(TableNum, RowNum, RowNum); + +impl ReferenceIndex { + pub fn new(id: TableNum, tag: TypedTag<RowNum>) -> Self { + Self { id, tag } } pub fn lookup<'a>( &self, db: &'a dyn ReadTransaction, - key: &[u8], + to: RowNum, ) -> Result<PrefixIterator<'a>> { let mut prefix = Vec::new(); prefix.extend(self.id.to_be_bytes()); - prefix.extend(key); + prefix.extend(to.to_be_bytes()); Ok(PrefixIterator { inner: db.iter(&prefix, false)?, prefix: prefix.into(), }) } } -impl Index for KeyIndex { +impl Index for ReferenceIndex { fn add(&self, db: &mut dyn WriteTransaction, id: RowNum, val: Object) -> Result<()> { - // db.set(&self.key(id, (self.key)(val)), &[]) + for to in val.iter(self.tag) { + db.set(bytes_of(&Key(self.id, to, id)), &[])?; + } + Ok(()) } fn remove(&self, db: &mut dyn WriteTransaction, id: RowNum, val: Object) -> Result<()> { - // db.del(&self.key(id, (self.key)(val))) + for to in val.iter(self.tag) { + db.del(bytes_of(&Key(self.id, to, id)))?; + } + Ok(()) } fn compare(&self, before: Object, after: Object) -> bool { - // (self.key)(before) == (self.key)(after) + let mut before = before.iter(self.tag); + let mut after = after.iter(self.tag); + loop { + let b = before.next(); + let a = after.next(); + if a.is_none() && b.is_none() { + break true; + } + if a != b { + break false; + } + } } } - -// fn inc_key(key: &[u8]) -> Vec<u8> { -// let mut key = key.to_owned(); -// for i in (0..key.len()).rev() { -// let (nv, carry) = key[i].overflowing_add(1); -// key[i] = nv; -// if !carry { -// break; -// } -// } -// key -// } diff --git a/database/src/lib.rs b/database/src/lib.rs index 40bda72..32d160b 100644 --- a/database/src/lib.rs +++ b/database/src/lib.rs @@ -5,7 +5,21 @@ */ pub mod backends; pub mod indices; -pub mod table; pub mod prefix_iterator; +pub mod table; pub type Pad32 = u32; + +use jellycommon::jellyobject::{Object, Tag, TypedTag}; + +enum Query<'a> { + MatchStr(Match<'a, &'a str>), + MatchF64(Match<'a, f64>), + MatchU64(Match<'a, u64>), + MatchTag(Match<'a, Tag>), + Has(Path<'a>), +} + +pub struct Match<'a, T>(pub TypedPath<'a, T>, pub T); +pub struct TypedPath<'a, T>(pub &'a [TypedTag<Object<'static>>], pub TypedTag<T>); +pub struct Path<'a>(pub &'a [TypedTag<Object<'static>>], pub Tag); |