aboutsummaryrefslogtreecommitdiff
path: root/database/src/kv
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-02-10 01:11:36 +0100
committermetamuffin <metamuffin@disroot.org>2026-02-10 01:11:36 +0100
commitf035474090d3c82f50c3860cbafd6f60b8af36e8 (patch)
treead05b9df5770bee3c1f020870911f7744977422d /database/src/kv
parent7754a042ed80c7d8e2391925a8a6ae87a7610c8e (diff)
downloadjellything-f035474090d3c82f50c3860cbafd6f60b8af36e8.tar
jellything-f035474090d3c82f50c3860cbafd6f60b8af36e8.tar.bz2
jellything-f035474090d3c82f50c3860cbafd6f60b8af36e8.tar.zst
fix index key ser; query debug print
Diffstat (limited to 'database/src/kv')
-rw-r--r--database/src/kv/index.rs1
-rw-r--r--database/src/kv/index_key.rs35
-rw-r--r--database/src/kv/mod.rs39
3 files changed, 69 insertions, 6 deletions
diff --git a/database/src/kv/index.rs b/database/src/kv/index.rs
index 81a4f55..23b8349 100644
--- a/database/src/kv/index.rs
+++ b/database/src/kv/index.rs
@@ -63,7 +63,6 @@ pub fn iter_index<'a>(
prefix: Vec<u8>,
sort: &Sort,
) -> Result<Box<dyn Iterator<Item = Result<(RowNum, Vec<u8>)>> + 'a>> {
- eprintln!("{prefix:?}");
Ok(match sort {
Sort::None => Box::new(
PrefixIterator {
diff --git a/database/src/kv/index_key.rs b/database/src/kv/index_key.rs
index a4b2f01..adfc3e8 100644
--- a/database/src/kv/index_key.rs
+++ b/database/src/kv/index_key.rs
@@ -12,7 +12,7 @@ use crate::{
};
use jellyobject::{Path, Tag};
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Eq)]
pub struct IndexKey(pub Binning, pub SortKey);
#[derive(Debug, Hash, PartialEq, Eq)]
@@ -45,7 +45,7 @@ impl IndexKey {
b = &b[4..]; // remove subtree prefix
let binning = Binning::read(&mut b);
let sort = SortKey::read(&mut b);
- assert!(b.is_empty());
+ assert!(b.is_empty(), "index key deser left-over bytes");
Self(binning, sort)
}
}
@@ -85,6 +85,7 @@ impl Binning {
impl SortKey {
fn read(b: &mut &[u8]) -> Self {
let ty = b[0];
+ *b = &b[1..];
match ty {
0 => SortKey::None,
1 => SortKey::Count,
@@ -108,6 +109,7 @@ impl SortKey {
SortKey::None => out.push(0),
SortKey::Count => out.push(1),
SortKey::Value(path, multi_behaviour) => {
+ out.push(2);
write_path(path, out);
out.push(match multi_behaviour {
MultiBehaviour::First => 0,
@@ -118,6 +120,7 @@ impl SortKey {
});
}
SortKey::Text(path) => {
+ out.push(3);
write_path(path, out);
}
}
@@ -141,3 +144,31 @@ fn read_path(b: &mut &[u8]) -> Path {
}
Path(o)
}
+
+#[cfg(test)]
+mod test {
+ use jellyobject::{Path, Tag};
+
+ use crate::kv::{
+ binning::{Binning, BinningComponent},
+ index_key::{IndexKey, SortKey},
+ };
+
+ #[test]
+ fn serialize() {
+ let t = |k: IndexKey| {
+ let b = k.to_bytes();
+ let k2 = IndexKey::from_bytes(&b);
+ assert_eq!(k, k2);
+ };
+
+ t(IndexKey(
+ Binning(vec![BinningComponent::Match(Path(vec![Tag(1001)]))]),
+ SortKey::None,
+ ));
+ t(IndexKey(
+ Binning(vec![BinningComponent::Has(Path(vec![Tag(123), Tag(456)]))]),
+ SortKey::Text(Path(vec![Tag(789)])),
+ ));
+ }
+}
diff --git a/database/src/kv/mod.rs b/database/src/kv/mod.rs
index 8d42ec7..903fc46 100644
--- a/database/src/kv/mod.rs
+++ b/database/src/kv/mod.rs
@@ -15,7 +15,7 @@ pub mod sort;
use std::borrow::Cow;
use crate::{
- Database, Query, RowNum, Transaction,
+ DEBUG_TAGREG, Database, Query, RowNum, Transaction,
kv::{
helpers::{read_counter, write_counter},
index::{iter_index, read_count_index, update_index},
@@ -25,7 +25,8 @@ use crate::{
},
};
use anyhow::{Result, anyhow};
-use jellyobject::ObjectBuffer;
+use jellyobject::{ObjectBuffer, inspect::Inspector};
+use log::{debug, info};
pub type SubtreeNum = u32;
@@ -44,6 +45,9 @@ impl<T: jellykv::Store> Database for T {
impl Transaction for &mut dyn jellykv::Transaction {
fn insert(&mut self, entry: ObjectBuffer) -> Result<RowNum> {
+ if let Some(tr) = DEBUG_TAGREG.get() {
+ debug!("insert {:?}", Inspector(tr, entry.as_object()))
+ }
let mut id_counter = read_counter(*self, &T_ROW_COUNTER.to_be_bytes(), 0)?;
let row = id_counter;
id_counter += 1;
@@ -97,6 +101,7 @@ impl Transaction for &mut dyn jellykv::Transaction {
&'a mut self,
query: Query,
) -> Result<Box<dyn Iterator<Item = Result<(RowNum, Vec<u8>)>> + 'a>> {
+ debug!("query: {}", query.show_debug());
let mut prefixes = Vec::new();
for (binning, mut prefix) in query.filter.get_bins() {
let ik = IndexKey(binning, query.sort.key());
@@ -151,6 +156,7 @@ fn alloc_subtree(txn: &mut dyn jellykv::Transaction) -> Result<SubtreeNum> {
}
fn create_index(txn: &mut dyn jellykv::Transaction, is: SubtreeNum, ik: &IndexKey) -> Result<()> {
+ info!("creating new index {is}: {ik:?}");
let rowkeys = PrefixIterator {
inner: txn.iter(&T_ROWS.to_be_bytes(), false)?,
prefix: Cow::Borrowed(&T_ROWS.to_be_bytes()),
@@ -246,7 +252,7 @@ mod test {
}
#[test]
- pub fn query_match() -> Result<()> {
+ pub fn query_match_int() -> Result<()> {
let db = jellykv::memory::new();
let mut rows = [0, 0, 0];
@@ -271,4 +277,31 @@ mod test {
assert_eq!(result, Some(rows[0]));
Ok(())
}
+
+ #[test]
+ pub fn query_match_str() -> Result<()> {
+ let db = jellykv::memory::new();
+
+ let mut rows = [0, 0, 0];
+ let mut result = None;
+
+ db.transaction(&mut |txn| {
+ rows = [
+ txn.insert(new_bob())?,
+ txn.insert(new_alice())?,
+ txn.insert(new_charlie())?,
+ ];
+ Ok(())
+ })?;
+ db.transaction(&mut |txn| {
+ result = txn.query_single(Query {
+ filter: Filter::Match(Path(vec![NAME.0]), "Alice".as_bytes().to_vec()),
+ sort: Sort::None,
+ })?;
+ Ok(())
+ })?;
+
+ assert_eq!(result, Some(rows[1]));
+ Ok(())
+ }
}