MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / register_index

Method register_index

nodedb/src/engine/kv/engine_index.rs:18–76  ·  view source on GitHub ↗

Register a secondary index on a field for a collection. If `backfill` is true, scans all existing entries and populates the index. Returns the number of entries backfilled (0 if index already existed). Note**: backfill scans all entries synchronously. For large collections (> 10k entries), consider `backfill=false` and rebuilding offline.

(
        &mut self,
        tenant_id: u64,
        collection: &str,
        field: &str,
        field_position: usize,
        backfill: bool,
        now_ms: u64,
    )

Source from the content-addressed store, hash-verified

16 /// **Note**: backfill scans all entries synchronously. For large collections
17 /// (> 10k entries), consider `backfill=false` and rebuilding offline.
18 pub fn register_index(
19 &mut self,
20 tenant_id: u64,
21 collection: &str,
22 field: &str,
23 field_position: usize,
24 backfill: bool,
25 now_ms: u64,
26 ) -> usize {
27 let tkey = table_key(tenant_id, collection);
28 let idx_set = self.indexes.entry(tkey).or_default();
29
30 if !idx_set.add_index(field, field_position) {
31 return 0; // Already indexed.
32 }
33
34 if !backfill {
35 return 0;
36 }
37
38 // Backfill: collect entries first, then update indexes.
39 // Two-phase approach avoids borrow conflicts on self.indexes vs self.tables.
40 let entries_to_backfill: Vec<(Vec<u8>, Vec<u8>)> = match self.tables.get(&tkey) {
41 Some(table) => {
42 let mut all = Vec::new();
43 let mut cursor = 0;
44 loop {
45 let (entries, next) = table.scan(cursor, 1000, now_ms, None);
46 if entries.is_empty() {
47 break;
48 }
49 all.extend(entries.into_iter().map(|(k, v)| (k.to_vec(), v.to_vec())));
50 if next == 0 {
51 break;
52 }
53 cursor = next;
54 }
55 all
56 }
57 None => return 0,
58 };
59
60 // Now update indexes — idx_set is guaranteed to exist (inserted above).
61 let idx_set = self
62 .indexes
63 .get_mut(&tkey)
64 .expect("index set was inserted at entry point of register_index");
65 let mut backfilled = 0;
66 for (key, value) in &entries_to_backfill {
67 let field_values = extract_field_values_from_msgpack(value, field);
68 for fv in &field_values {
69 let fv_pairs: Vec<(&str, &[u8])> = vec![(field, fv.as_slice())];
70 idx_set.on_put(key, &fv_pairs, None);
71 backfilled += 1;
72 }
73 }
74
75 backfilled

Callers 6

index_maintained_on_putFunction · 0.80
index_cleaned_on_deleteFunction · 0.80
write_amp_trackingFunction · 0.80

Calls 12

table_keyFunction · 0.85
entryMethod · 0.80
add_indexMethod · 0.45
getMethod · 0.45
scanMethod · 0.45
is_emptyMethod · 0.45
extendMethod · 0.45
to_vecMethod · 0.45
expectMethod · 0.45
get_mutMethod · 0.45
on_putMethod · 0.45

Tested by 5

index_maintained_on_putFunction · 0.64
index_cleaned_on_deleteFunction · 0.64
write_amp_trackingFunction · 0.64