aboutsummaryrefslogtreecommitdiff
path: root/database/src/indices/order.rs
blob: 91636811cc4b4e35c771307b0a532e33cb579723 (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
40
/*
    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,
    indices::Index,
    table::{RowNum, Table, TableNum},
};
use anyhow::Result;
use bytemuck::{NoUninit, bytes_of};

pub struct OrderIndex<T> {
    id: TableNum,
    value: fn(&T) -> [u8; 8],
}

#[repr(C)]
#[derive(NoUninit, Clone, Copy)]
struct Key(TableNum, [u8; 8], RowNum);

impl<T: 'static> OrderIndex<T> {
    pub fn new(table: &mut Table<T>, id: TableNum, value: fn(&T) -> [u8; 8]) -> Self {
        table.indices.push(Box::new(Self { id, value }));
        Self { id, value }
    }
}
impl<T: 'static> Index<T> for OrderIndex<T> {
    fn add(&self, db: &mut dyn WriteTransaction, id: RowNum, val: &T) -> Result<()> {
        db.set(bytes_of(&Key(self.id, (self.value)(val), id)), &[])
    }
    fn remove(&self, db: &mut dyn WriteTransaction, id: RowNum, val: &T) -> Result<()> {
        db.del(bytes_of(&Key(self.id, (self.value)(val), id)))
    }
    fn compare(&self, before: &T, after: &T) -> bool {
        (self.value)(before) == (self.value)(after)
    }
}