flusql/src/core/index.rs

123 lines
3.9 KiB
Rust
Raw Normal View History

2026-01-15 19:38:57 +00:00
//! Модуль управления индексами
use std::collections::{HashMap, HashSet};
use crate::parser::sql::Value;
use std::sync::atomic::{AtomicU64, Ordering};
use atomic_refcell::AtomicRefCell;
/// Индекс для быстрого поиска с поддержкой MVCC
#[derive(Debug)]
pub struct Index {
name: String,
data: AtomicRefCell<HashMap<Value, HashSet<u64>>>,
version: AtomicU64,
}
impl Clone for Index {
fn clone(&self) -> Self {
let data = self.data.borrow();
Self {
name: self.name.clone(),
data: AtomicRefCell::new(data.clone()),
version: AtomicU64::new(self.version.load(Ordering::Relaxed)),
}
}
}
impl Index {
/// Создание нового индекса
pub fn new(name: &str) -> Self {
Self {
name: name.to_string(),
data: AtomicRefCell::new(HashMap::new()),
version: AtomicU64::new(1),
}
}
/// Вставка значения в индекс (wait-free)
pub fn insert(&self, value: Value, record_id: u64) {
let mut data = self.data.borrow_mut();
data.entry(value)
.or_insert_with(HashSet::new)
.insert(record_id);
self.version.fetch_add(1, Ordering::SeqCst);
}
/// Поиск по значению (wait-free чтение)
pub fn search(&self, value: &Value) -> Option<HashSet<u64>> {
let data = self.data.borrow();
data.get(value).cloned()
}
/// Удаление значения из индекса
pub fn remove(&self, value: &Value, record_id: u64) {
let mut data = self.data.borrow_mut();
if let Some(set) = data.get_mut(value) {
set.remove(&record_id);
if set.is_empty() {
data.remove(value);
}
self.version.fetch_add(1, Ordering::SeqCst);
}
}
/// Получение всех значений индекса (wait-free)
pub fn get_all(&self) -> Vec<Value> {
let data = self.data.borrow();
data.keys().cloned().collect()
}
/// Очистка индекса
pub fn clear(&mut self) {
let mut data = self.data.borrow_mut();
data.clear();
self.version.fetch_add(1, Ordering::SeqCst);
}
/// Получение имени индекса
pub fn name(&self) -> &str {
&self.name
}
/// Получение версии индекса
pub fn version(&self) -> u64 {
self.version.load(Ordering::Relaxed)
}
/// Массовая вставка записей (оптимизированная)
pub fn bulk_insert(&self, values: Vec<(Value, u64)>) {
let mut data = self.data.borrow_mut();
for (value, record_id) in values {
data.entry(value)
.or_insert_with(HashSet::new)
.insert(record_id);
}
self.version.fetch_add(1, Ordering::SeqCst);
}
/// Поиск по диапазону (для упорядоченных типов)
pub fn range_search(&self, start: &Value, end: &Value) -> HashSet<u64> {
let data = self.data.borrow();
let mut result = HashSet::new();
for (key, record_ids) in data.iter() {
// Упрощенная реализация - только для сравнимых типов
match (key, start, end) {
(Value::Integer(k), Value::Integer(s), Value::Integer(e)) => {
if k >= s && k <= e {
result.extend(record_ids);
}
}
(Value::Text(k), Value::Text(s), Value::Text(e)) => {
if k >= s && k <= e {
result.extend(record_ids);
}
}
_ => {}
}
}
result
}
}