aboutsummaryrefslogtreecommitdiff
path: root/database/src/kv/sort
diff options
context:
space:
mode:
Diffstat (limited to 'database/src/kv/sort')
-rw-r--r--database/src/kv/sort/mod.rs29
-rw-r--r--database/src/kv/sort/none.rs50
-rw-r--r--database/src/kv/sort/value.rs86
3 files changed, 165 insertions, 0 deletions
diff --git a/database/src/kv/sort/mod.rs b/database/src/kv/sort/mod.rs
new file mode 100644
index 0000000..403ba73
--- /dev/null
+++ b/database/src/kv/sort/mod.rs
@@ -0,0 +1,29 @@
+/*
+ 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 jellyobject::Path;
+
+use crate::{MultiBehaviour, Sort};
+
+pub mod none;
+pub mod value;
+
+#[derive(Hash, PartialEq, Eq)]
+pub enum SortKey {
+ None,
+ Value(Path, MultiBehaviour),
+ Text(Path),
+}
+
+impl Sort {
+ pub fn key(&self) -> SortKey {
+ match self {
+ Sort::None => SortKey::None,
+ Sort::Value(vs) => SortKey::Value(vs.path.clone(), vs.multi),
+ Sort::TextSearch(p, _) => SortKey::Text(p.to_owned()),
+ }
+ }
+}
diff --git a/database/src/kv/sort/none.rs b/database/src/kv/sort/none.rs
new file mode 100644
index 0000000..b4d5db2
--- /dev/null
+++ b/database/src/kv/sort/none.rs
@@ -0,0 +1,50 @@
+/*
+ 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::{
+ RowNum,
+ kv::{TableNum, binning::Binning},
+};
+use jellyobject::Object;
+
+pub struct UnsortedIndex {
+ id: TableNum,
+ binning: Binning,
+}
+
+impl UnsortedIndex {
+ pub fn new(id: TableNum, binning: Binning) -> Self {
+ Self { id, binning }
+ }
+ fn keys(&self, id: RowNum, ob: Object) -> Vec<Vec<u8>> {
+ let mut keys = vec![self.id.to_be_bytes().to_vec()];
+ self.binning.apply(ob, &mut keys);
+ for k in &mut keys {
+ k.extend(id.to_ne_bytes());
+ }
+ keys
+ }
+}
+// impl Index for UnsortedIndex {
+// fn add(&self, db: &mut dyn WriteTransaction, id: RowNum, ob: Object) -> Result<()> {
+// for key in self.keys(id, ob) {
+// db.set(&key, &[])?;
+// }
+// Ok(())
+// }
+// fn remove(&self, db: &mut dyn WriteTransaction, id: RowNum, ob: Object) -> Result<()> {
+// for key in self.keys(id, ob) {
+// db.del(&key)?;
+// }
+// Ok(())
+// }
+// fn compare(&self, before: Object, after: Object) -> bool {
+// self.keys(0, before) == self.keys(0, after)
+// }
+// fn query(&self, txn: &mut dyn ReadTransaction, _sort: &Sort) -> Result<RowIter> {
+// todo!()
+// }
+// }
diff --git a/database/src/kv/sort/value.rs b/database/src/kv/sort/value.rs
new file mode 100644
index 0000000..0d4ceb7
--- /dev/null
+++ b/database/src/kv/sort/value.rs
@@ -0,0 +1,86 @@
+/*
+ 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 jellyobject::Object;
+
+use crate::{
+ MultiBehaviour, RowNum, ValueSort,
+ kv::{TableNum, binning::Binning},
+};
+
+pub struct ValueIndex {
+ id: TableNum,
+ binning: Binning,
+ sort: ValueSort,
+}
+
+impl ValueIndex {
+ pub fn new(id: TableNum, binning: Binning, sort: ValueSort) -> Self {
+ Self { id, binning, sort }
+ }
+ fn keys(&self, id: RowNum, ob: Object) -> Vec<Vec<u8>> {
+ let mut keys = vec![self.id.to_be_bytes().to_vec()];
+ self.binning.apply(ob, &mut keys);
+ self.sort.apply(ob, &mut keys);
+ for k in &mut keys {
+ k.extend(id.to_ne_bytes());
+ }
+ keys
+ }
+}
+// impl Index for ValueIndex {
+// fn add(&self, db: &mut dyn WriteTransaction, id: RowNum, ob: Object) -> Result<()> {
+// for key in self.keys(id, ob) {
+// db.set(&key, &[])?;
+// }
+// Ok(())
+// }
+// fn remove(&self, db: &mut dyn WriteTransaction, id: RowNum, ob: Object) -> Result<()> {
+// for key in self.keys(id, ob) {
+// db.del(&key)?;
+// }
+// Ok(())
+// }
+// fn compare(&self, before: Object, after: Object) -> bool {
+// self.keys(0, before) == self.keys(0, after)
+// }
+// fn query(&self, txn: &mut dyn ReadTransaction, sort: &Sort) -> Result<RowIter> {
+// todo!()
+// }
+// }
+impl ValueSort {
+ fn apply(&self, ob: Object, keys: &mut Vec<Vec<u8>>) {
+ match self.multi {
+ MultiBehaviour::First => {
+ if let Some(val) = self.path.get_matching_value(ob) {
+ for k in keys.iter_mut() {
+ k.extend(val);
+ }
+ } else {
+ keys.clear();
+ }
+ }
+ MultiBehaviour::ForEach => {
+ let mut keys_out = Vec::new();
+ for val in self.path.get_matching_values(ob) {
+ for mut k in keys.clone() {
+ k.extend(val);
+ keys_out.push(k);
+ }
+ }
+ *keys = keys_out
+ }
+ MultiBehaviour::Max => todo!(),
+ MultiBehaviour::Min => todo!(),
+ MultiBehaviour::Count => {
+ let count = self.path.get_matching_values(ob).len() as u32;
+ for k in keys.iter_mut() {
+ k.extend(count.to_be_bytes());
+ }
+ }
+ }
+ }
+}