diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-02-05 20:31:55 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-02-05 20:31:55 +0100 |
| commit | 65ca3f3450d0067668111f6e13cc3089768c9efe (patch) | |
| tree | 89dceed4f711d25ff2763e18a4be7e1a59e79507 /database/src/kv/counters.rs | |
| parent | 1af0468788c0a592a76398206e6c7479384853ec (diff) | |
| download | jellything-65ca3f3450d0067668111f6e13cc3089768c9efe.tar jellything-65ca3f3450d0067668111f6e13cc3089768c9efe.tar.bz2 jellything-65ca3f3450d0067668111f6e13cc3089768c9efe.tar.zst | |
remove read/write distinction for kv transactions; traitify database
Diffstat (limited to 'database/src/kv/counters.rs')
| -rw-r--r-- | database/src/kv/counters.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/database/src/kv/counters.rs b/database/src/kv/counters.rs new file mode 100644 index 0000000..fae7b42 --- /dev/null +++ b/database/src/kv/counters.rs @@ -0,0 +1,59 @@ +/* + 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::{ + Query, RowNum, + kv::{self, TableNum, binning::Binning}, +}; +use anyhow::Result; +use jellyobject::Object; +use std::collections::HashMap; + +pub(crate) struct Counters(pub HashMap<Binning, TableNum>); +impl Counters { + pub fn update( + &self, + txn: &mut dyn jellykv::Transaction, + ob: Object<'_>, + remove: bool, + ) -> Result<()> { + for (b, &table) in &self.0 { + let mut k = vec![vec![]]; + b.apply(ob, &mut k); + if k.is_empty() { + continue; + } + let mut counter = read_counter(txn, table)?; + if remove { + counter += k.len() as u64; + } else { + counter -= k.len() as u64; + } + write_counter(txn, table, counter)?; + } + Ok(()) + } + pub fn count(&self, txn: &dyn jellykv::Transaction, query: &Query) -> Result<Option<u64>> { + let mut total = 0; + for binning in query.filter.get_bins() { + let Some(b) = self.0.get(&binning) else { + return Ok(None); + }; + total += read_counter(txn, *b)?; + } + Ok(Some(total)) + } +} + +pub fn write_counter(txn: &mut dyn jellykv::Transaction, t: TableNum, value: u64) -> Result<()> { + txn.set(&t.to_be_bytes(), &value.to_be_bytes()) +} +pub fn read_counter(txn: &dyn jellykv::Transaction, t: TableNum) -> Result<u64> { + Ok(txn + .get(&t.to_be_bytes())? + .map(|k| k.as_slice().try_into().map(RowNum::from_be_bytes).ok()) + .flatten() + .unwrap_or(0)) +} |