flusql/src/core/index.rs

123 lines
3.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! Модуль управления индексами
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
}
}