aboutsummaryrefslogtreecommitdiff
path: root/database/src/kv/counters.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-02-05 20:31:55 +0100
committermetamuffin <metamuffin@disroot.org>2026-02-05 20:31:55 +0100
commit65ca3f3450d0067668111f6e13cc3089768c9efe (patch)
tree89dceed4f711d25ff2763e18a4be7e1a59e79507 /database/src/kv/counters.rs
parent1af0468788c0a592a76398206e6c7479384853ec (diff)
downloadjellything-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.rs59
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))
+}