aboutsummaryrefslogtreecommitdiff
path: root/database/src/table.rs
diff options
context:
space:
mode:
Diffstat (limited to 'database/src/table.rs')
-rw-r--r--database/src/table.rs184
1 files changed, 0 insertions, 184 deletions
diff --git a/database/src/table.rs b/database/src/table.rs
deleted file mode 100644
index ee8d66b..0000000
--- a/database/src/table.rs
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- 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::{
- 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 = u32;
-pub type RowNum = u64;
-
-pub type RowIter = Box<dyn Iterator<Item = Result<RowNum>>>;
-pub type IndexKey = (Binning, SortKey);
-
-pub struct Table {
- id: TableNum,
- pub(crate) counters: HashMap<Binning, TableNum>,
- pub(crate) indices: HashMap<IndexKey, TableNum>,
-}
-impl Table {
- pub fn new(id: u32) -> Self {
- Self {
- id,
- counters: HashMap::new(),
- indices: HashMap::new(),
- }
- }
- fn key(&self, row: RowNum) -> Vec<u8> {
- let mut key = Vec::new();
- key.extend(self.id.to_be_bytes());
- 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 = read_counter(txn, self.id)?;
- let row = id_counter;
- id_counter += 1;
- 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.values() {
- idx.add(txn, row, ob)?;
- }
-
- Ok(row)
- }
- pub fn get(&self, txn: &dyn ReadTransaction, row: RowNum) -> Result<Option<ObjectBuffer>> {
- Ok(txn.get(&self.key(row))?.map(ObjectBuffer::from))
- }
- pub fn remove(&self, db: &mut dyn WriteTransaction, row: RowNum) -> Result<bool> {
- let Some(entry) = self.get(db, row)? else {
- return Ok(false);
- };
- let ob = entry.as_object();
- for index in self.indices.values() {
- index.remove(db, row, ob)?;
- }
- db.del(&self.key(row))?;
- Ok(true)
- }
- pub fn update(
- &self,
- txn: &mut dyn WriteTransaction,
- row: RowNum,
- entry: ObjectBuffer,
- ) -> Result<()> {
- let before = self
- .get(txn, row)?
- .ok_or(anyhow!("row to update missing"))?;
- let before = before.as_object();
- let after = entry.as_object();
-
- txn.set(&self.key(row), bytemuck::cast_slice(entry.0.as_slice()))?;
-
- for index in self.indices.values() {
- if !index.compare(before, after) {
- index.remove(txn, row, before)?;
- index.add(txn, row, after)?;
- }
- }
-
- Ok(())
- }
- 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()
- }
- 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)
- }
-}
-
-#[cfg(test)]
-mod test {
- use crate::{
- table::Table,
- test_shared::{NAME, new_bob},
- };
- use anyhow::Result;
- use jellykv::Database;
-
- #[test]
- pub fn insert_get() -> Result<()> {
- let db = jellykv::memory::new();
- let table = Table::new(5);
-
- let mut bob_row = 0;
- db.write_transaction(&mut |txn| {
- bob_row = table.insert(txn, new_bob())?;
- Ok(())
- })?;
-
- let mut bob = None;
- db.read_transaction(&mut |txn| {
- bob = table.get(txn, bob_row)?;
- Ok(())
- })?;
-
- assert_eq!(bob.unwrap().as_object().get(NAME).unwrap(), "Bob");
- Ok(())
- }
-
- #[test]
- pub fn update() -> Result<()> {
- let db = jellykv::memory::new();
- let table = Table::new(5);
-
- let mut bob_row = 0;
- let mut bob = None;
-
- db.write_transaction(&mut |txn| {
- bob_row = table.insert(txn, new_bob())?;
- Ok(())
- })?;
- db.write_transaction(&mut |txn| {
- let better_bob = new_bob().as_object().insert(NAME, "Better Bob");
- table.update(txn, bob_row, better_bob)?;
- Ok(())
- })?;
- db.read_transaction(&mut |txn| {
- bob = table.get(txn, bob_row)?;
- Ok(())
- })?;
-
- assert_eq!(bob.unwrap().as_object().get(NAME).unwrap(), "Better Bob");
- Ok(())
- }
-}