aboutsummaryrefslogtreecommitdiff
path: root/database/src/table.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-02-04 16:23:29 +0100
committermetamuffin <metamuffin@disroot.org>2026-02-04 16:23:29 +0100
commit1af0468788c0a592a76398206e6c7479384853ec (patch)
tree1860ec77be705a0715cc4c90c51176b22fabfca8 /database/src/table.rs
parent088b6b323130b0a9509c76f395c7ed4bf5609234 (diff)
downloadjellything-1af0468788c0a592a76398206e6c7479384853ec.tar
jellything-1af0468788c0a592a76398206e6c7479384853ec.tar.bz2
jellything-1af0468788c0a592a76398206e6c7479384853ec.tar.zst
stuff
Diffstat (limited to 'database/src/table.rs')
-rw-r--r--database/src/table.rs74
1 files changed, 49 insertions, 25 deletions
diff --git a/database/src/table.rs b/database/src/table.rs
index ad3775a..ee8d66b 100644
--- a/database/src/table.rs
+++ b/database/src/table.rs
@@ -4,24 +4,35 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use crate::{query::Query, sort::Index};
+use crate::{
+ counters::{read_counter, write_counter},
+ filter::binning::Binning,
+ prefix_iterator::PrefixIterator,
+ query::Query,
+ sort::{Index, SortKey},
+};
use anyhow::{Result, anyhow};
use jellykv::{ReadTransaction, WriteTransaction};
use jellyobject::ObjectBuffer;
use std::collections::HashMap;
-pub type TableNum = u64;
+pub type TableNum = u32;
pub type RowNum = u64;
+pub type RowIter = Box<dyn Iterator<Item = Result<RowNum>>>;
+pub type IndexKey = (Binning, SortKey);
+
pub struct Table {
- id: u32,
- pub(crate) indices: HashMap<IndexKey, Box<dyn Index>>,
+ id: TableNum,
+ pub(crate) counters: HashMap<Binning, TableNum>,
+ pub(crate) indices: HashMap<IndexKey, TableNum>,
}
impl Table {
pub fn new(id: u32) -> Self {
Self {
id,
- indices: Vec::new(),
+ counters: HashMap::new(),
+ indices: HashMap::new(),
}
}
fn key(&self, row: RowNum) -> Vec<u8> {
@@ -30,29 +41,28 @@ impl Table {
key.extend(row.to_be_bytes());
key
}
+ pub fn iter(&self, txn: &dyn ReadTransaction) -> Result<impl Iterator<Item = Result<RowNum>>> {
+ Ok(PrefixIterator {
+ inner: txn.iter(&self.id.to_be_bytes(), false)?,
+ prefix: self.id.to_be_bytes().to_vec().into(),
+ }
+ .map(|r| r.map(|r| RowNum::from_be_bytes(r.try_into().unwrap()))))
+ }
pub fn insert(&self, txn: &mut dyn WriteTransaction, entry: ObjectBuffer) -> Result<RowNum> {
- let mut id_counter = txn
- .get(&self.id.to_be_bytes())?
- .map(|k| k.as_slice().try_into().map(RowNum::from_be_bytes).ok())
- .flatten()
- .unwrap_or(0);
+ let mut id_counter = read_counter(txn, self.id)?;
let row = id_counter;
id_counter += 1;
- txn.set(&self.id.to_be_bytes(), &id_counter.to_be_bytes())?;
+ write_counter(txn, self.id, id_counter)?;
txn.set(&self.key(row), bytemuck::cast_slice(entry.0.as_slice()))?;
let ob = entry.as_object();
- for idx in &self.indices {
+ for idx in self.indices.values() {
idx.add(txn, row, ob)?;
}
Ok(row)
}
- pub fn add_index<T: Index + Clone + 'static>(&mut self, index: T) -> T {
- self.indices.push(Box::new(index.clone()));
- index
- }
pub fn get(&self, txn: &dyn ReadTransaction, row: RowNum) -> Result<Option<ObjectBuffer>> {
Ok(txn.get(&self.key(row))?.map(ObjectBuffer::from))
}
@@ -61,8 +71,8 @@ impl Table {
return Ok(false);
};
let ob = entry.as_object();
- for idx in &self.indices {
- idx.remove(db, row, ob)?;
+ for index in self.indices.values() {
+ index.remove(db, row, ob)?;
}
db.del(&self.key(row))?;
Ok(true)
@@ -81,7 +91,7 @@ impl Table {
txn.set(&self.key(row), bytemuck::cast_slice(entry.0.as_slice()))?;
- for index in &self.indices {
+ for index in self.indices.values() {
if !index.compare(before, after) {
index.remove(txn, row, before)?;
index.add(txn, row, after)?;
@@ -90,15 +100,29 @@ impl Table {
Ok(())
}
- pub fn query(
- &self,
- txn: &dyn ReadTransaction,
- query: Query,
- ) -> Box<dyn Iterator<Item = Result<RowNum>>> {
+ pub fn query(&self, txn: &dyn ReadTransaction, query: Query) -> Result<RowIter> {
+ // query
+ // .filter
+ // .get_bins()
+ // .into_iter()
+ // .flat_map(|b| {
+ // let ikey = (b, query.sort.key());
+ // self.indices.get(&ikey)
+ // })
+ // .map(|i| i.query(txn, &query.sort))
todo!()
}
pub fn query_single(&self, txn: &dyn ReadTransaction, query: Query) -> Result<Option<RowNum>> {
- self.query(txn, query).next().transpose()
+ self.query(txn, query)?.next().transpose()
+ }
+ pub fn count(&self, txn: &dyn ReadTransaction, query: Query) -> Result<u64> {
+ let mut total = 0;
+ for b in query.filter.get_bins() {
+ if let Some(&c) = self.counters.get(&b) {
+ total += read_counter(txn, c)?;
+ }
+ }
+ Ok(total)
}
}