1use std::collections::{BTreeMap, HashMap};
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub enum IndexType {
34 BTree,
36 Hash,
38 FullText,
40}
41
42impl std::fmt::Display for IndexType {
43 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44 match self {
45 IndexType::BTree => write!(f, "BTree"),
46 IndexType::Hash => write!(f, "Hash"),
47 IndexType::FullText => write!(f, "FullText"),
48 }
49 }
50}
51
52pub trait Index: Send + Sync {
54 fn insert(&mut self, key: &[u8], value: u64) -> crate::Result<()>;
57
58 fn find(&self, key: &[u8]) -> crate::Result<Vec<u64>>;
60
61 fn remove(&mut self, key: &[u8]) -> crate::Result<bool>;
64
65 fn len(&self) -> usize;
67
68 fn is_empty(&self) -> bool {
70 self.len() == 0
71 }
72
73 fn clear(&mut self);
75
76 fn index_type(&self) -> IndexType;
78}
79
80#[derive(Debug, Clone)]
115pub struct BTreeIndex {
116 tree: BTreeMap<Vec<u8>, Vec<u64>>,
118 entry_count: usize,
120}
121
122impl BTreeIndex {
123 pub fn new() -> Self {
125 Self {
126 tree: BTreeMap::new(),
127 entry_count: 0,
128 }
129 }
130
131 pub fn range(&self, start: &[u8], end: &[u8]) -> crate::Result<Vec<(Vec<u8>, Vec<u64>)>> {
135 use std::ops::Bound;
136
137 let results: Vec<_> = self
138 .tree
139 .range((Bound::Included(start.to_vec()), Bound::Included(end.to_vec())))
140 .map(|(k, v)| (k.clone(), v.clone()))
141 .collect();
142
143 Ok(results)
144 }
145
146 pub fn prefix_scan(&self, prefix: &[u8]) -> crate::Result<Vec<(Vec<u8>, Vec<u64>)>> {
150 let results: Vec<_> = self
151 .tree
152 .range(prefix.to_vec()..)
153 .take_while(|(k, _)| k.starts_with(prefix))
154 .map(|(k, v)| (k.clone(), v.clone()))
155 .collect();
156
157 Ok(results)
158 }
159
160 pub fn min_key(&self) -> Option<&[u8]> {
162 self.tree.keys().next().map(|k| k.as_slice())
163 }
164
165 pub fn max_key(&self) -> Option<&[u8]> {
167 self.tree.keys().next_back().map(|k| k.as_slice())
168 }
169
170 pub fn iter(&self) -> impl Iterator<Item = (&[u8], &[u64])> {
172 self.tree.iter().map(|(k, v)| (k.as_slice(), v.as_slice()))
173 }
174}
175
176impl Default for BTreeIndex {
177 fn default() -> Self {
178 Self::new()
179 }
180}
181
182impl Index for BTreeIndex {
183 fn insert(&mut self, key: &[u8], value: u64) -> crate::Result<()> {
184 self.tree
185 .entry(key.to_vec())
186 .or_insert_with(Vec::new)
187 .push(value);
188 self.entry_count += 1;
189 Ok(())
190 }
191
192 fn find(&self, key: &[u8]) -> crate::Result<Vec<u64>> {
193 Ok(self.tree.get(key).cloned().unwrap_or_default())
194 }
195
196 fn remove(&mut self, key: &[u8]) -> crate::Result<bool> {
197 if let Some(values) = self.tree.remove(key) {
198 self.entry_count -= values.len();
199 Ok(true)
200 } else {
201 Ok(false)
202 }
203 }
204
205 fn len(&self) -> usize {
206 self.entry_count
207 }
208
209 fn clear(&mut self) {
210 self.tree.clear();
211 self.entry_count = 0;
212 }
213
214 fn index_type(&self) -> IndexType {
215 IndexType::BTree
216 }
217}
218
219#[derive(Debug, Clone)]
253pub struct HashIndex {
254 map: HashMap<Vec<u8>, Vec<u64>>,
256 entry_count: usize,
258}
259
260impl HashIndex {
261 pub fn new() -> Self {
263 Self {
264 map: HashMap::new(),
265 entry_count: 0,
266 }
267 }
268
269 pub fn with_capacity(capacity: usize) -> Self {
271 Self {
272 map: HashMap::with_capacity(capacity),
273 entry_count: 0,
274 }
275 }
276
277 pub fn contains_key(&self, key: &[u8]) -> bool {
279 self.map.contains_key(key)
280 }
281
282 pub fn key_count(&self) -> usize {
284 self.map.len()
285 }
286
287 pub fn iter(&self) -> impl Iterator<Item = (&[u8], &[u64])> {
289 self.map.iter().map(|(k, v)| (k.as_slice(), v.as_slice()))
290 }
291}
292
293impl Default for HashIndex {
294 fn default() -> Self {
295 Self::new()
296 }
297}
298
299impl Index for HashIndex {
300 fn insert(&mut self, key: &[u8], value: u64) -> crate::Result<()> {
301 self.map
302 .entry(key.to_vec())
303 .or_insert_with(Vec::new)
304 .push(value);
305 self.entry_count += 1;
306 Ok(())
307 }
308
309 fn find(&self, key: &[u8]) -> crate::Result<Vec<u64>> {
310 Ok(self.map.get(key).cloned().unwrap_or_default())
311 }
312
313 fn remove(&mut self, key: &[u8]) -> crate::Result<bool> {
314 if let Some(values) = self.map.remove(key) {
315 self.entry_count -= values.len();
316 Ok(true)
317 } else {
318 Ok(false)
319 }
320 }
321
322 fn len(&self) -> usize {
323 self.entry_count
324 }
325
326 fn clear(&mut self) {
327 self.map.clear();
328 self.entry_count = 0;
329 }
330
331 fn index_type(&self) -> IndexType {
332 IndexType::Hash
333 }
334}
335
336pub struct IndexManager {
361 indexes: HashMap<String, Box<dyn Index>>,
363}
364
365impl IndexManager {
366 pub fn new() -> Self {
368 Self {
369 indexes: HashMap::new(),
370 }
371 }
372
373 pub fn create_index(&mut self, name: &str, index_type: IndexType) -> crate::Result<()> {
375 if self.indexes.contains_key(name) {
376 return Err(crate::Error::InvalidOperation(format!(
377 "Index '{}' already exists",
378 name
379 )));
380 }
381
382 let index: Box<dyn Index> = match index_type {
383 IndexType::BTree => Box::new(BTreeIndex::new()),
384 IndexType::Hash => Box::new(HashIndex::new()),
385 IndexType::FullText => {
386 return Err(crate::Error::InvalidOperation(
387 "FullText index not yet implemented".to_string(),
388 ))
389 }
390 };
391
392 self.indexes.insert(name.to_string(), index);
393 Ok(())
394 }
395
396 pub fn drop_index(&mut self, name: &str) -> crate::Result<bool> {
398 Ok(self.indexes.remove(name).is_some())
399 }
400
401 pub fn get_index(&self, name: &str) -> Option<&dyn Index> {
403 self.indexes.get(name).map(|b| b.as_ref())
404 }
405
406 pub fn get_index_mut(&mut self, name: &str) -> Option<&mut (dyn Index + 'static)> {
408 self.indexes.get_mut(name).map(|b| b.as_mut())
409 }
410
411 pub fn insert(&mut self, name: &str, key: &[u8], value: u64) -> crate::Result<()> {
413 let index = self.indexes.get_mut(name).ok_or_else(|| {
414 crate::Error::NotFound
415 })?;
416 index.insert(key, value)
417 }
418
419 pub fn find(&self, name: &str, key: &[u8]) -> crate::Result<Vec<u64>> {
421 let index = self.indexes.get(name).ok_or_else(|| {
422 crate::Error::NotFound
423 })?;
424 index.find(key)
425 }
426
427 pub fn remove(&mut self, name: &str, key: &[u8]) -> crate::Result<bool> {
429 let index = self.indexes.get_mut(name).ok_or_else(|| {
430 crate::Error::NotFound
431 })?;
432 index.remove(key)
433 }
434
435 pub fn list_indexes(&self) -> Vec<&str> {
437 self.indexes.keys().map(|s| s.as_str()).collect()
438 }
439
440 pub fn index_info(&self) -> Vec<IndexInfo> {
442 self.indexes
443 .iter()
444 .map(|(name, index)| IndexInfo {
445 name: name.clone(),
446 index_type: index.index_type(),
447 entry_count: index.len(),
448 })
449 .collect()
450 }
451}
452
453impl Default for IndexManager {
454 fn default() -> Self {
455 Self::new()
456 }
457}
458
459#[derive(Debug, Clone)]
461pub struct IndexInfo {
462 pub name: String,
464 pub index_type: IndexType,
466 pub entry_count: usize,
468}
469
470#[cfg(test)]
475mod tests {
476 use super::*;
477
478 #[test]
479 fn test_btree_index_basic_operations() {
480 let mut index = BTreeIndex::new();
481
482 index.insert(b"key1", 100).unwrap();
484 index.insert(b"key2", 200).unwrap();
485 index.insert(b"key1", 101).unwrap(); assert_eq!(index.find(b"key1").unwrap(), vec![100, 101]);
489 assert_eq!(index.find(b"key2").unwrap(), vec![200]);
490 assert!(index.find(b"key3").unwrap().is_empty());
491
492 assert_eq!(index.len(), 3);
494
495 assert!(index.remove(b"key1").unwrap());
497 assert!(!index.remove(b"key1").unwrap());
498 assert_eq!(index.len(), 1);
499 }
500
501 #[test]
502 fn test_btree_index_range_query() {
503 let mut index = BTreeIndex::new();
504
505 index.insert(b"a", 1).unwrap();
506 index.insert(b"b", 2).unwrap();
507 index.insert(b"c", 3).unwrap();
508 index.insert(b"d", 4).unwrap();
509 index.insert(b"e", 5).unwrap();
510
511 let range = index.range(b"b", b"d").unwrap();
512 assert_eq!(range.len(), 3);
513 assert_eq!(range[0].0, b"b");
514 assert_eq!(range[1].0, b"c");
515 assert_eq!(range[2].0, b"d");
516 }
517
518 #[test]
519 fn test_btree_index_prefix_scan() {
520 let mut index = BTreeIndex::new();
521
522 index.insert(b"user:001", 1).unwrap();
523 index.insert(b"user:002", 2).unwrap();
524 index.insert(b"user:003", 3).unwrap();
525 index.insert(b"order:001", 10).unwrap();
526 index.insert(b"order:002", 20).unwrap();
527
528 let users = index.prefix_scan(b"user:").unwrap();
529 assert_eq!(users.len(), 3);
530
531 let orders = index.prefix_scan(b"order:").unwrap();
532 assert_eq!(orders.len(), 2);
533 }
534
535 #[test]
536 fn test_btree_index_min_max() {
537 let mut index = BTreeIndex::new();
538
539 assert!(index.min_key().is_none());
540 assert!(index.max_key().is_none());
541
542 index.insert(b"middle", 2).unwrap();
543 index.insert(b"first", 1).unwrap();
544 index.insert(b"last", 3).unwrap();
545
546 assert_eq!(index.min_key(), Some(b"first".as_slice()));
547 assert_eq!(index.max_key(), Some(b"middle".as_slice()));
548 }
549
550 #[test]
551 fn test_hash_index_basic_operations() {
552 let mut index = HashIndex::new();
553
554 index.insert(b"session:abc", 100).unwrap();
556 index.insert(b"session:def", 200).unwrap();
557 index.insert(b"session:abc", 101).unwrap();
558
559 assert_eq!(index.find(b"session:abc").unwrap(), vec![100, 101]);
561 assert_eq!(index.find(b"session:def").unwrap(), vec![200]);
562 assert!(index.find(b"session:xyz").unwrap().is_empty());
563
564 assert!(index.contains_key(b"session:abc"));
566 assert!(!index.contains_key(b"session:xyz"));
567
568 assert_eq!(index.len(), 3);
570 assert_eq!(index.key_count(), 2);
571 }
572
573 #[test]
574 fn test_hash_index_with_capacity() {
575 let index = HashIndex::with_capacity(100);
576 assert!(index.is_empty());
577 }
578
579 #[test]
580 fn test_index_manager() {
581 let mut manager = IndexManager::new();
582
583 manager.create_index("users", IndexType::Hash).unwrap();
585 manager.create_index("names", IndexType::BTree).unwrap();
586
587 assert!(manager.create_index("users", IndexType::Hash).is_err());
589
590 manager.insert("users", b"user:1", 100).unwrap();
592 manager.insert("names", b"alice", 100).unwrap();
593 manager.insert("names", b"bob", 101).unwrap();
594
595 assert_eq!(manager.find("users", b"user:1").unwrap(), vec![100]);
597 assert_eq!(manager.find("names", b"alice").unwrap(), vec![100]);
598
599 let names = manager.list_indexes();
601 assert_eq!(names.len(), 2);
602
603 let info = manager.index_info();
605 assert_eq!(info.len(), 2);
606
607 assert!(manager.drop_index("users").unwrap());
609 assert!(!manager.drop_index("users").unwrap());
610 assert_eq!(manager.list_indexes().len(), 1);
611 }
612
613 #[test]
614 fn test_index_clear() {
615 let mut btree = BTreeIndex::new();
616 let mut hash = HashIndex::new();
617
618 btree.insert(b"key", 1).unwrap();
619 hash.insert(b"key", 1).unwrap();
620
621 assert!(!btree.is_empty());
622 assert!(!hash.is_empty());
623
624 btree.clear();
625 hash.clear();
626
627 assert!(btree.is_empty());
628 assert!(hash.is_empty());
629 }
630}