velesdb_core/collection/core/
index_management.rs1use crate::collection::types::Collection;
4use crate::error::Result;
5use crate::index::{JsonValue, SecondaryIndex};
6use parking_lot::RwLock;
7use std::collections::BTreeMap;
8
9#[derive(Debug, Clone)]
11pub struct IndexInfo {
12 pub label: String,
14 pub property: String,
16 pub index_type: String,
18 pub cardinality: usize,
20 pub memory_bytes: usize,
22}
23
24impl Collection {
25 pub fn create_index(&self, field_name: &str) -> Result<()> {
31 let mut indexes = self.secondary_indexes.write();
32 indexes
33 .entry(field_name.to_string())
34 .or_insert_with(|| SecondaryIndex::BTree(RwLock::new(BTreeMap::new())));
35 Ok(())
36 }
37
38 #[must_use]
40 pub fn has_secondary_index(&self, field_name: &str) -> bool {
41 self.secondary_indexes.read().contains_key(field_name)
42 }
43
44 #[must_use]
46 pub fn secondary_index_lookup(&self, field_name: &str, value: &JsonValue) -> Option<Vec<u64>> {
47 let indexes = self.secondary_indexes.read();
48 let index = indexes.get(field_name)?;
49 match index {
50 SecondaryIndex::BTree(tree) => tree.read().get(value).cloned(),
51 }
52 }
53
54 pub fn create_property_index(&self, label: &str, property: &str) -> Result<()> {
65 let mut index = self.property_index.write();
66 index.create_index(label, property);
67 Ok(())
68 }
69
70 pub fn create_range_index(&self, label: &str, property: &str) -> Result<()> {
81 let mut index = self.range_index.write();
82 index.create_index(label, property);
83 Ok(())
84 }
85
86 #[must_use]
88 pub fn has_property_index(&self, label: &str, property: &str) -> bool {
89 self.property_index.read().has_index(label, property)
90 }
91
92 #[must_use]
94 pub fn has_range_index(&self, label: &str, property: &str) -> bool {
95 self.range_index.read().has_index(label, property)
96 }
97
98 #[must_use]
100 pub fn list_indexes(&self) -> Vec<IndexInfo> {
101 let mut indexes = Vec::new();
102
103 let prop_index = self.property_index.read();
105 for (label, property) in prop_index.indexed_properties() {
106 let cardinality = prop_index.cardinality(&label, &property).unwrap_or(0);
107 indexes.push(IndexInfo {
108 label,
109 property,
110 index_type: "hash".to_string(),
111 cardinality,
112 memory_bytes: 0, });
114 }
115
116 let range_idx = self.range_index.read();
118 for (label, property) in range_idx.indexed_properties() {
119 indexes.push(IndexInfo {
120 label,
121 property,
122 index_type: "range".to_string(),
123 cardinality: 0, memory_bytes: 0,
125 });
126 }
127
128 indexes
129 }
130
131 pub fn drop_index(&self, label: &str, property: &str) -> Result<bool> {
146 let dropped_prop = self.property_index.write().drop_index(label, property);
148 if dropped_prop {
149 return Ok(true);
150 }
151
152 let dropped_range = self.range_index.write().drop_index(label, property);
154 Ok(dropped_range)
155 }
156
157 #[must_use]
159 pub fn indexes_memory_usage(&self) -> usize {
160 let prop_mem = self.property_index.read().memory_usage();
161 let range_mem = self.range_index.read().memory_usage();
162 prop_mem + range_mem
163 }
164}