aboutsummaryrefslogtreecommitdiff
path: root/database/src/indices/order.rs
blob: 04fb97525ea42241c865d4724779ffb4469c8b4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
    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) 2025 metamuffin <metamuffin.org>
*/

use crate::{backends::KV, indices::Index, table::Table};
use anyhow::Result;

pub struct OrderIndex<T> {
    id: u32,
    value: fn(&T) -> [u8; 8],
}
impl<T: 'static> OrderIndex<T> {
    pub fn new(table: &mut Table<T>, id: u32, value: fn(&T) -> [u8; 8]) -> Self {
        table.indices.push(Box::new(Self { id, value }));
        Self { id, value }
    }
    fn key(&self, id: u64, val: &T) -> Vec<u8> {
        let mut key = Vec::new();
        key.extend(self.id.to_be_bytes());
        key.extend((self.value)(val));
        key.extend(id.to_be_bytes());
        key
    }
}
impl<T: 'static> Index<T> for OrderIndex<T> {
    fn add(&self, db: &dyn KV, id: u64, val: &T) -> Result<()> {
        db.set(&self.key(id, val), &[])?;
        Ok(())
    }
    fn remove(&self, db: &dyn KV, id: u64, val: &T) -> Result<()> {
        db.del(&self.key(id, val))?;
        Ok(())
    }
    fn compare(&self, before: &T, after: &T) -> bool {
        (self.value)(before) == (self.value)(after)
    }
}