aboutsummaryrefslogtreecommitdiff
path: root/database/src/sort
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 /database/src/sort
parentb5ff460e938779be4eeab292c2cc1d436b93c137 (diff)
downloadjellything-abf25f340c11111369b69c13c34d8fed9d4f0da8.tar
jellything-abf25f340c11111369b69c13c34d8fed9d4f0da8.tar.bz2
jellything-abf25f340c11111369b69c13c34d8fed9d4f0da8.tar.zst
db binning and sorts
Diffstat (limited to 'database/src/sort')
-rw-r--r--database/src/sort/mod.rs22
-rw-r--r--database/src/sort/none.rs50
-rw-r--r--database/src/sort/value.rs86
3 files changed, 158 insertions, 0 deletions
diff --git a/database/src/sort/mod.rs b/database/src/sort/mod.rs
new file mode 100644
index 0000000..6473f5d
--- /dev/null
+++ b/database/src/sort/mod.rs
@@ -0,0 +1,22 @@
+/*
+ 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::{backends::WriteTransaction, table::RowNum};
+use anyhow::Result;
+use jellycommon::jellyobject::Object;
+
+pub mod none;
+pub mod value;
+
+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<()>;
+ /// Might return true if objects are identical for this index; false if not or uncertain
+ fn compare(&self, before: Object, after: Object) -> bool {
+ let _ = (before, after);
+ false
+ }
+}
diff --git a/database/src/sort/none.rs b/database/src/sort/none.rs
new file mode 100644
index 0000000..b17cb29
--- /dev/null
+++ b/database/src/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::{
+ backends::WriteTransaction,
+ filter::binning::Binning,
+ sort::Index,
+ table::{RowNum, TableNum},
+};
+use anyhow::Result;
+use jellycommon::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)
+ }
+}
diff --git a/database/src/sort/value.rs b/database/src/sort/value.rs
new file mode 100644
index 0000000..0381fe0
--- /dev/null
+++ b/database/src/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 crate::{
+ backends::WriteTransaction,
+ filter::binning::Binning,
+ query::{MultiBehaviour, ValueSortComponent},
+ sort::Index,
+ table::{RowNum, TableNum},
+};
+use anyhow::Result;
+use jellycommon::jellyobject::Object;
+
+pub struct ValueIndex {
+ id: TableNum,
+ binning: Binning,
+ sort: ValueSortComponent,
+}
+
+impl ValueIndex {
+ pub fn new(id: TableNum, binning: Binning, sort: ValueSortComponent) -> 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)
+ }
+}
+impl ValueSortComponent {
+ 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());
+ }
+ }
+ }
+ }
+}