aboutsummaryrefslogtreecommitdiff
path: root/database/src/sort/value.rs
diff options
context:
space:
mode:
Diffstat (limited to 'database/src/sort/value.rs')
-rw-r--r--database/src/sort/value.rs86
1 files changed, 86 insertions, 0 deletions
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());
+ }
+ }
+ }
+ }
+}