use std::sync::atomic::AtomicUsize;
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use super::fulltext_index::FulltextRegistry;
use super::index_catalog::{IndexCatalog, StoredIndexEntity};
use super::point_index::PointRegistry;
use super::property_index::PropertyIndexRegistry;
use super::sorted_property_index::SortedPropertyIndex;
use super::text_index::TrigramRegistry;
#[derive(Debug, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
pub(super) struct ScopedPropertyKey {
pub label: String,
pub property: String,
}
impl ScopedPropertyKey {
pub(super) fn new(label: &str, property: &str) -> Self {
Self {
label: label.to_string(),
property: property.to_string(),
}
}
}
#[derive(Debug, Default)]
pub(super) struct EntityIndexStore<T> {
node: RwLock<T>,
relationship: RwLock<T>,
}
impl<T> EntityIndexStore<T> {
pub(super) fn read(&self, entity: StoredIndexEntity) -> RwLockReadGuard<'_, T> {
self.lock_for(entity)
.read()
.unwrap_or_else(|poisoned| poisoned.into_inner())
}
pub(super) fn write(&self, entity: StoredIndexEntity) -> RwLockWriteGuard<'_, T> {
self.lock_for(entity)
.write()
.unwrap_or_else(|poisoned| poisoned.into_inner())
}
fn lock_for(&self, entity: StoredIndexEntity) -> &RwLock<T> {
match entity {
StoredIndexEntity::Node => &self.node,
StoredIndexEntity::Relationship => &self.relationship,
}
}
}
impl<T: Clone> Clone for EntityIndexStore<T> {
fn clone(&self) -> Self {
Self {
node: RwLock::new(self.read(StoredIndexEntity::Node).clone()),
relationship: RwLock::new(self.read(StoredIndexEntity::Relationship).clone()),
}
}
}
#[derive(Debug, Default)]
pub(super) struct IndexBundle {
pub(super) catalog: RwLock<IndexCatalog>,
pub(super) properties: RwLock<PropertyIndexRegistry>,
pub(super) text: EntityIndexStore<TrigramRegistry>,
pub(super) sorted: EntityIndexStore<SortedPropertyIndex>,
pub(super) point: EntityIndexStore<PointRegistry>,
pub(super) fulltext: EntityIndexStore<FulltextRegistry>,
pub(super) active_node_property_indexes: AtomicUsize,
pub(super) active_relationship_property_indexes: AtomicUsize,
pub(super) active_fulltext_indexes: AtomicUsize,
}
impl Clone for IndexBundle {
fn clone(&self) -> Self {
use std::sync::atomic::Ordering;
let properties = self
.properties
.read()
.map(|g| g.clone())
.unwrap_or_default();
let catalog = self.catalog.read().map(|g| g.clone()).unwrap_or_default();
Self {
catalog: RwLock::new(catalog),
properties: RwLock::new(properties),
text: self.text.clone(),
sorted: self.sorted.clone(),
point: self.point.clone(),
fulltext: self.fulltext.clone(),
active_node_property_indexes: AtomicUsize::new(
self.active_node_property_indexes.load(Ordering::Relaxed),
),
active_relationship_property_indexes: AtomicUsize::new(
self.active_relationship_property_indexes
.load(Ordering::Relaxed),
),
active_fulltext_indexes: AtomicUsize::new(
self.active_fulltext_indexes.load(Ordering::Relaxed),
),
}
}
}