From 5878f47bf7b28e1cea548fa9631d28db954ae371 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Wed, 11 Mar 2026 17:34:35 +0100 Subject: db test for changes before re-indexing --- database/src/kv/index.rs | 28 ++++++++++++++++++++++++++++ database/src/kv/mod.rs | 10 +++++++--- kv/src/rocksdb.rs | 2 +- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/database/src/kv/index.rs b/database/src/kv/index.rs index 5ceab1c..2c96b48 100644 --- a/database/src/kv/index.rs +++ b/database/src/kv/index.rs @@ -8,6 +8,7 @@ use crate::{ MultiBehaviour, RowNum, Sort, SortOrder, kv::{ SubtreeNum, + binning::BinningComponent, helpers::{read_counter, write_counter}, index_key::{IndexKey, SortKey}, prefix_iterator::PrefixIterator, @@ -17,6 +18,33 @@ use anyhow::{Result, bail}; use jellyobject::Object; use std::{collections::HashSet, iter::empty}; +pub fn test_index_identical(ik: &IndexKey, before: &Object, after: &Object) -> bool { + let mut identical = true; + for b in &ik.0.0 { + match b { + BinningComponent::Has(path) => { + identical &= path.get_matching_value(before).is_some() + == path.get_matching_value(after).is_some(); + } + BinningComponent::Match(path) => { + identical &= path.get_matching_values(before) == path.get_matching_values(after); + } + } + } + match &ik.1 { + SortKey::None | SortKey::Count | SortKey::Random => (), + SortKey::Value(path, _) => { + identical &= path.get_matching_values(before) == path.get_matching_values(after); + } + SortKey::Text(paths) => { + for p in paths { + identical &= p.get_matching_values(before) == p.get_matching_values(after); + } + } + } + identical +} + pub fn update_index( txn: &mut dyn jellykv::Transaction, is: SubtreeNum, diff --git a/database/src/kv/mod.rs b/database/src/kv/mod.rs index f391d31..0ce4683 100644 --- a/database/src/kv/mod.rs +++ b/database/src/kv/mod.rs @@ -17,7 +17,7 @@ use crate::{ Database, Query, RowNum, Transaction, kv::{ helpers::{read_counter, write_counter}, - index::{iter_index, read_count_index, update_index}, + index::{iter_index, read_count_index, test_index_identical, update_index}, index_key::{IndexKey, SortKey}, merge_iterator::MergeIterator, prefix_iterator::PrefixIterator, @@ -85,12 +85,16 @@ impl Transaction for &mut dyn jellykv::Transaction { } fn update(&mut self, row: RowNum, entry: Box) -> Result<()> { debug!("update {row}"); + let after = &entry; let before = self.get(row)?.ok_or(anyhow!("row to update missing"))?; - jellykv::Transaction::set(*self, &row_key(row), bytemuck::cast_slice(entry.export()))?; + jellykv::Transaction::set(*self, &row_key(row), bytemuck::cast_slice(after.export()))?; for (is, ik) in list_indices(*self)? { + if test_index_identical(&ik, &before, &after) { + continue; + } update_index(*self, is, &ik, row, &before, true)?; - update_index(*self, is, &ik, row, &entry, false)?; + update_index(*self, is, &ik, row, &after, false)?; } Ok(()) diff --git a/kv/src/rocksdb.rs b/kv/src/rocksdb.rs index 04d7437..50e7e74 100644 --- a/kv/src/rocksdb.rs +++ b/kv/src/rocksdb.rs @@ -43,7 +43,7 @@ impl Store for OptimisticTransactionDB { Ok(format!( "transactions attempted: {attempts:>12}\n\ transactions commited: {commits:>12}\n\ - transactions retry factor: {retry_factor:>12.03}\n\ + transaction retry factor: {retry_factor:>12.03}\n\ approximate size on disk: {:>12}\n", SizeFormatter::new(size, DECIMAL).to_string() )) -- cgit v1.3