ixa/entity/index/
mod.rs

1//! Index types for property-value lookups.
2
3use crate::entity::{Entity, EntityId};
4use crate::hashing::IndexSet;
5use crate::prelude::Property;
6
7mod full_index;
8mod value_count_index;
9
10pub use full_index::*;
11pub use value_count_index::*;
12
13#[derive(Debug)]
14pub enum IndexSetResult<'a, E: Entity> {
15    /// The index type cannot satisfy the query.
16    Unsupported,
17    /// The set is empty.
18    Empty,
19    /// A reference to the index set.
20    Set(&'a IndexSet<EntityId<E>>),
21}
22
23#[derive(PartialEq, Eq, Debug)]
24pub enum IndexCountResult {
25    /// The index type cannot satisfy the query.
26    Unsupported,
27    /// The count of entities.
28    Count(usize),
29}
30
31#[derive(Debug, Copy, Clone, PartialEq, Eq)]
32pub enum PropertyIndexType {
33    Unindexed,
34    FullIndex,
35    ValueCountIndex,
36}
37
38pub enum PropertyIndex<E: Entity, P: Property<E>> {
39    Unindexed,
40    FullIndex(FullIndex<E, P>),
41    ValueCountIndex(ValueCountIndex<E, P>),
42}
43
44impl<E: Entity, P: Property<E>> PropertyIndex<E, P> {
45    pub fn index_type(&self) -> PropertyIndexType {
46        match self {
47            Self::Unindexed => PropertyIndexType::Unindexed,
48            Self::FullIndex(_) => PropertyIndexType::FullIndex,
49            Self::ValueCountIndex(_) => PropertyIndexType::ValueCountIndex,
50        }
51    }
52
53    pub fn get_index_set_result(&self, value: &P::CanonicalValue) -> IndexSetResult<'_, E> {
54        match self {
55            Self::Unindexed => IndexSetResult::<'_, E>::Unsupported,
56            Self::FullIndex(index) => match index.get(value) {
57                Some(set) => IndexSetResult::Set(set),
58                None => IndexSetResult::Empty,
59            },
60            Self::ValueCountIndex(_) => IndexSetResult::<'_, E>::Unsupported,
61        }
62    }
63
64    pub fn get_index_count_result(&self, value: &P::CanonicalValue) -> IndexCountResult {
65        match self {
66            Self::Unindexed => IndexCountResult::Unsupported,
67            Self::FullIndex(index) => {
68                let count = index.get(value).map_or(0, |set| set.len());
69                IndexCountResult::Count(count)
70            }
71            Self::ValueCountIndex(index) => IndexCountResult::Count(index.get(value).unwrap_or(0)),
72        }
73    }
74
75    pub fn remove_entity(&mut self, value: &P::CanonicalValue, entity_id: EntityId<E>) {
76        match self {
77            Self::Unindexed => {}
78            Self::FullIndex(index) => index.remove_entity(value, entity_id),
79            Self::ValueCountIndex(index) => index.remove_entity(value, entity_id),
80        }
81    }
82
83    pub fn add_entity(&mut self, value: &P::CanonicalValue, entity_id: EntityId<E>) {
84        match self {
85            Self::Unindexed => {}
86            Self::FullIndex(index) => {
87                index.add_entity(value, entity_id);
88            }
89            Self::ValueCountIndex(index) => {
90                index.add_entity(value, entity_id);
91            }
92        }
93    }
94
95    /// Returns `None` if there is no index.
96    pub fn max_indexed(&self) -> Option<usize> {
97        match self {
98            Self::Unindexed => None,
99            Self::FullIndex(index) => Some(index.max_indexed),
100            Self::ValueCountIndex(index) => Some(index.max_indexed),
101        }
102    }
103
104    pub fn set_max_indexed(&mut self, max_indexed: usize) {
105        match self {
106            Self::Unindexed => {}
107            Self::FullIndex(index) => index.max_indexed = max_indexed,
108            Self::ValueCountIndex(index) => index.max_indexed = max_indexed,
109        }
110    }
111}