aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-01-11 02:51:24 +0100
committermetamuffin <metamuffin@disroot.org>2026-01-11 02:51:24 +0100
commit72a718fffb236c4b157e4d62c2e486ca7b326a26 (patch)
tree17acd02fcd88dca48ce92e94d950a413d1cc8340
parent095d4234558c39f28ddc777f123a15e410a74c14 (diff)
downloadjellything-72a718fffb236c4b157e4d62c2e486ca7b326a26.tar
jellything-72a718fffb236c4b157e4d62c2e486ca7b326a26.tar.bz2
jellything-72a718fffb236c4b157e4d62c2e486ca7b326a26.tar.zst
things
-rw-r--r--common/object/src/lib.rs39
-rw-r--r--database/src/indices/mod.rs6
-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.rs16
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);