diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-02-04 16:23:29 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-02-04 16:23:29 +0100 |
| commit | 1af0468788c0a592a76398206e6c7479384853ec (patch) | |
| tree | 1860ec77be705a0715cc4c90c51176b22fabfca8 /database/src/table.rs | |
| parent | 088b6b323130b0a9509c76f395c7ed4bf5609234 (diff) | |
| download | jellything-1af0468788c0a592a76398206e6c7479384853ec.tar jellything-1af0468788c0a592a76398206e6c7479384853ec.tar.bz2 jellything-1af0468788c0a592a76398206e6c7479384853ec.tar.zst | |
stuff
Diffstat (limited to 'database/src/table.rs')
| -rw-r--r-- | database/src/table.rs | 74 |
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) } } |