aboutsummaryrefslogtreecommitdiff
path: root/database/src/kv
diff options
context:
space:
mode:
Diffstat (limited to 'database/src/kv')
-rw-r--r--database/src/kv/index.rs38
-rw-r--r--database/src/kv/index_key.rs5
-rw-r--r--database/src/kv/merge_iterator.rs1
3 files changed, 42 insertions, 2 deletions
diff --git a/database/src/kv/index.rs b/database/src/kv/index.rs
index 7a3a5b1..60d291c 100644
--- a/database/src/kv/index.rs
+++ b/database/src/kv/index.rs
@@ -15,6 +15,7 @@ use crate::{
};
use anyhow::Result;
use jellyobject::Object;
+use std::iter::empty;
pub fn update_index(
txn: &mut dyn jellykv::Transaction,
@@ -37,6 +38,16 @@ pub fn update_index(
}
}
}
+ SortKey::Random => {
+ for mut k in ks {
+ k.extend(randomize(row).to_be_bytes());
+ if remove {
+ txn.del(&k)?;
+ } else {
+ txn.set(&k, &row.to_be_bytes())?;
+ }
+ }
+ }
SortKey::Count => {
for k in ks {
let mut c = read_counter(txn, &k, 0)?;
@@ -62,7 +73,7 @@ pub fn update_index(
}
}
}
- SortKey::Text(path) => {}
+ SortKey::Text(_) => todo!(),
}
Ok(())
}
@@ -91,6 +102,20 @@ pub fn iter_index<'a>(
})
}),
),
+ Sort::Random(seed) => {
+ let mut k = prefix.clone();
+ k.extend(randomize(*seed).to_be_bytes());
+ let Some(it) = txn.iter(&k, false)?.next() else {
+ return Ok(Box::new(empty()));
+ };
+ let res = it?;
+ if !res.starts_with(&prefix) {
+ return Ok(Box::new(empty()));
+ }
+ let r = txn.get(&res)?.unwrap();
+ let row = RowNum::from_be_bytes(r.try_into().unwrap());
+ Box::new([Ok((row, vec![]))].into_iter())
+ }
Sort::Value(value_sort) => {
assert!(value_sort.offset.is_none(), "TODO");
Box::new(
@@ -111,7 +136,7 @@ pub fn iter_index<'a>(
}),
)
}
- Sort::TextSearch(path, _) => todo!(),
+ Sort::TextSearch(_, _) => todo!(),
})
}
@@ -125,3 +150,12 @@ fn prefix_end(mut prefix: Vec<u8>) -> Vec<u8> {
}
prefix
}
+
+fn randomize(mut x: u64) -> u64 {
+ for _ in 0..15 {
+ x ^= x << 13;
+ x ^= x >> 7;
+ x ^= x << 17;
+ }
+ x
+}
diff --git a/database/src/kv/index_key.rs b/database/src/kv/index_key.rs
index fae7d4a..ec8f183 100644
--- a/database/src/kv/index_key.rs
+++ b/database/src/kv/index_key.rs
@@ -21,6 +21,7 @@ pub struct IndexKey(pub Binning, pub SortKey);
pub enum SortKey {
None,
Count,
+ Random,
Value(Path, MultiBehaviour),
Text(Path),
}
@@ -29,6 +30,7 @@ impl Sort {
pub fn key(&self) -> SortKey {
match self {
Sort::None => SortKey::None,
+ Sort::Random(_) => SortKey::Random,
Sort::Value(vs) => SortKey::Value(vs.path.clone(), vs.multi),
Sort::TextSearch(p, _) => SortKey::Text(p.to_owned()),
}
@@ -90,6 +92,7 @@ impl SortKey {
*b = &b[1..];
match ty {
0 => SortKey::None,
+ 4 => SortKey::Random,
1 => SortKey::Count,
2 => SortKey::Value(read_path(b), {
let mb = b[0];
@@ -110,6 +113,7 @@ impl SortKey {
fn write(&self, out: &mut Vec<u8>) {
match self {
SortKey::None => out.push(0),
+ SortKey::Random => out.push(4),
SortKey::Count => out.push(1),
SortKey::Value(path, multi_behaviour) => {
out.push(2);
@@ -158,6 +162,7 @@ impl Display for SortKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SortKey::None => write!(f, "none"),
+ SortKey::Random => write!(f, "random"),
SortKey::Count => write!(f, "count"),
SortKey::Value(path, multi) => write!(f, "value({path}, {multi})"),
SortKey::Text(path) => write!(f, "text({path})"),
diff --git a/database/src/kv/merge_iterator.rs b/database/src/kv/merge_iterator.rs
index 5658416..8398ba4 100644
--- a/database/src/kv/merge_iterator.rs
+++ b/database/src/kv/merge_iterator.rs
@@ -18,6 +18,7 @@ impl<'a> MergeIterator<'a> {
impl<'a> Iterator for MergeIterator<'a> {
type Item = Result<(RowNum, Vec<u8>)>;
fn next(&mut self) -> Option<Self::Item> {
+ let _ = self.iters;
todo!()
}
}