aboutsummaryrefslogtreecommitdiff
path: root/database/src/filter/binning.rs
diff options
context:
space:
mode:
Diffstat (limited to 'database/src/filter/binning.rs')
-rw-r--r--database/src/filter/binning.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/database/src/filter/binning.rs b/database/src/filter/binning.rs
new file mode 100644
index 0000000..977d5d7
--- /dev/null
+++ b/database/src/filter/binning.rs
@@ -0,0 +1,52 @@
+/*
+ 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 jellycommon::jellyobject::{Object, path::Path};
+
+/// Sorted list of components to bin objects by filterable values.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct Binning(Vec<BinningComponent>);
+
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)]
+pub enum BinningComponent {
+ Has(Path),
+ Match(Path),
+}
+
+impl Binning {
+ pub fn new(mut comps: Vec<BinningComponent>) -> Self {
+ comps.sort();
+ Self(comps)
+ }
+ pub fn apply(&self, ob: Object<'_>, keys: &mut Vec<Vec<u8>>) {
+ for f in &self.0 {
+ f.apply(ob, keys);
+ }
+ }
+}
+impl BinningComponent {
+ pub fn apply(&self, ob: Object<'_>, keys: &mut Vec<Vec<u8>>) {
+ match self {
+ BinningComponent::Has(path) => {
+ let has = path.get_matching_value(ob).is_some();
+ for co in keys {
+ co.push(has as u8)
+ }
+ }
+ BinningComponent::Match(path) => {
+ let mut new_out = Vec::new();
+ for value in path.get_matching_values(ob) {
+ for mut co in keys.clone() {
+ co.extend((co.len() as u32).to_be_bytes());
+ co.extend(value);
+ new_out.push(co);
+ }
+ }
+ *keys = new_out;
+ }
+ }
+ }
+}