···
buckets: Vec<CursorBucket>,
) -> StorageResult<(JustCount, Vec<PrefixChild>, Option<Vec<u8>>)> {
668
+
// TODO: fix up this mess
669
+
// the lower/start bound is tricky because `Exclusive()` _without_ a null terminator _will_ include the null-
670
+
// terminated exact match. so we actually need the null terminator for an exclusive lower bound!
672
+
// but for upper/end bound, we *cannot* have a null terminator after the prefix, else we'll only get everything up
673
+
// until prefix+null (aka nothing).
675
+
let prefix_sub_with_null = prefix.as_str().to_string().to_db_bytes()?;
let prefix_sub = String::sub_prefix(prefix.as_str())?;
let cursor_child = cursor
let decoded: String = db_complete(encoded_bytes)?;
673
-
let as_sub_prefix = String::sub_prefix(&decoded)?;
674
-
Ok::<_, EncodingError>(as_sub_prefix)
681
+
let as_sub_prefix_with_null = decoded.to_db_bytes()?;
682
+
Ok::<_, EncodingError>(as_sub_prefix_with_null)
let mut iters: Vec<NsidCounter> = Vec::with_capacity(buckets.len());
···
.map(|child| HourlyRollupKey::after_nsid_prefix(*t, child))
684
-
.unwrap_or_else(|| HourlyRollupKey::after_nsid_prefix(*t, &prefix_sub))?;
692
+
.unwrap_or_else(|| {
693
+
HourlyRollupKey::after_nsid_prefix(*t, &prefix_sub_with_null)
let end = HourlyRollupKey::nsid_prefix_end(*t, &prefix_sub)?;
get_lexi_iter::<HourlyRollupKey>(&snapshot, start, end)?
···
.map(|child| WeeklyRollupKey::after_nsid_prefix(*t, child))
692
-
.unwrap_or_else(|| WeeklyRollupKey::after_nsid_prefix(*t, &prefix_sub))?;
702
+
.unwrap_or_else(|| {
703
+
WeeklyRollupKey::after_nsid_prefix(*t, &prefix_sub_with_null)
let end = WeeklyRollupKey::nsid_prefix_end(*t, &prefix_sub)?;
get_lexi_iter::<WeeklyRollupKey>(&snapshot, start, end)?
···
.map(|child| AllTimeRollupKey::after_nsid_prefix(child))
700
-
.unwrap_or_else(|| AllTimeRollupKey::after_nsid_prefix(&prefix_sub))?;
712
+
.unwrap_or_else(|| {
713
+
AllTimeRollupKey::after_nsid_prefix(&prefix_sub_with_null)
let end = AllTimeRollupKey::nsid_prefix_end(&prefix_sub)?;
get_lexi_iter::<AllTimeRollupKey>(&snapshot, start, end)?
···
let mut iters: Vec<_> = iters
712
-
it.map(|bla| bla.map(|(nsid, v)| (Child::from_prefix(&nsid, &prefix), v)))
727
+
bla.map(|(nsid, v)| {
728
+
let Some(child) = Child::from_prefix(&nsid, &prefix) else {
729
+
panic!("failed from_prefix: {nsid:?} {prefix:?} (bad iter bounds?)");
···
725
-
fn from_prefix(nsid: &Nsid, prefix: &NsidPrefix) -> Self {
746
+
fn from_prefix(nsid: &Nsid, prefix: &NsidPrefix) -> Option<Self> {
if prefix.is_group_of(nsid) {
727
-
Child::FullNsid(nsid.to_string())
731
-
.strip_prefix(&format!("{}.", prefix.0))
733
-
let (segment, _) = suffix.split_once('.').unwrap();
734
-
Child::ChildPrefix(format!("{}.{segment}", prefix.0))
748
+
return Some(Child::FullNsid(nsid.to_string()));
750
+
let suffix = nsid.as_str().strip_prefix(&format!("{}.", prefix.0))?;
751
+
let (segment, _) = suffix.split_once('.').unwrap();
752
+
let child_prefix = format!("{}.{segment}", prefix.0);
753
+
Some(Child::ChildPrefix(child_prefix))
fn is_before(&self, other: &Child) -> bool {
···
2471
-
fn get_nsid_prefix_children_lexi_empty() {
2489
+
fn get_prefix_children_lexi_empty() {
let (read, _) = fjall_db();
···
2498
-
fn get_nsid_prefix_children_lexi() -> anyhow::Result<()> {
2516
+
fn get_prefix_excludes_exact_collection() -> anyhow::Result<()> {
let (read, mut write) = fjall_db();
let mut batch = TestBatch::default();
···
2529
+
write.insert_batch(batch.batch)?;
2530
+
write.step_rollup()?;
2540
+
) = read.get_prefix(
2541
+
NsidPrefix::new("a.a.a").unwrap(),
2543
+
OrderCollectionsBy::Lexi { cursor: None },
2547
+
assert_eq!(creates, 0);
2548
+
assert_eq!(dids_estimate, 0);
2549
+
assert_eq!(children, vec![]);
2550
+
assert_eq!(cursor, None);
2555
+
fn get_prefix_includes_child_collection() -> anyhow::Result<()> {
2556
+
let (read, mut write) = fjall_db();
2558
+
let mut batch = TestBatch::default();
2568
+
write.insert_batch(batch.batch)?;
2569
+
write.step_rollup()?;
2579
+
) = read.get_prefix(
2580
+
NsidPrefix::new("a.a").unwrap(),
2582
+
OrderCollectionsBy::Lexi { cursor: None },
2586
+
assert_eq!(creates, 1);
2587
+
assert_eq!(dids_estimate, 1);
2590
+
vec![PrefixChild::Collection(NsidCount {
2591
+
nsid: "a.a.a".to_string(),
2596
+
assert_eq!(cursor, None);
2601
+
fn get_prefix_includes_child_prefix() -> anyhow::Result<()> {
2602
+
let (read, mut write) = fjall_db();
2604
+
let mut batch = TestBatch::default();
2521
-
"did:plc:person-b",
2606
+
"did:plc:person-a",
2530
-
"did:plc:person-a",
2614
+
write.insert_batch(batch.batch)?;
2615
+
write.step_rollup()?;
2625
+
) = read.get_prefix(
2626
+
NsidPrefix::new("a.a").unwrap(),
2628
+
OrderCollectionsBy::Lexi { cursor: None },
2632
+
assert_eq!(creates, 1);
2633
+
assert_eq!(dids_estimate, 1);
2636
+
vec![PrefixChild::Prefix(PrefixCount {
2637
+
prefix: "a.a.a".to_string(),
2642
+
assert_eq!(cursor, None);
2647
+
fn get_prefix_merges_child_prefixes() -> anyhow::Result<()> {
2648
+
let (read, mut write) = fjall_db();
2650
+
let mut batch = TestBatch::default();
2539
-
"did:plc:person-b",
2652
+
"did:plc:person-a",
write.insert_batch(batch.batch)?;
···
2575
-
assert_eq!(creates, 4);
2576
-
assert_eq!(dids_estimate, 2);
2687
+
assert_eq!(creates, 2);
2688
+
assert_eq!(dids_estimate, 1);
2580
-
PrefixChild::Collection(NsidCount {
2581
-
nsid: "a.a.a".to_string(),
2585
-
PrefixChild::Prefix(PrefixCount {
2586
-
prefix: "a.a.a".to_string(),
2691
+
vec![PrefixChild::Prefix(PrefixCount {
2692
+
prefix: "a.a.a".to_string(),
assert_eq!(cursor, None);
2702
+
fn get_prefix_exact_and_child_and_prefix() -> anyhow::Result<()> {
2703
+
let (read, mut write) = fjall_db();
2705
+
let mut batch = TestBatch::default();
2708
+
"did:plc:person-a",
2718
+
"did:plc:person-a",
2728
+
"did:plc:person-a",
2732
+
Some("rev-aaaaa"),
2736
+
write.insert_batch(batch.batch)?;
2737
+
write.step_rollup()?;
···
2609
-
assert_eq!(creates, 4);
2610
-
assert_eq!(dids_estimate, 2);
2754
+
assert_eq!(creates, 2);
2755
+
assert_eq!(dids_estimate, 1);
PrefixChild::Collection(NsidCount {
2615
-
nsid: "a.a.a".to_string(),
2760
+
nsid: "a.a.a.a".to_string(),
PrefixChild::Prefix(PrefixCount {
2620
-
prefix: "a.a.a".to_string(),
2765
+
prefix: "a.a.a.a".to_string(),
assert_eq!(cursor, None);