ixa/entity/index/
mod.rs

1//! Index types for property-value lookups.
2
3use crate::entity::{Entity, EntityId, HashValueType};
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 add_entity_with_hash(&mut self, hash: HashValueType, entity_id: EntityId<E>) {
54        match self {
55            Self::Unindexed => {}
56            Self::FullIndex(index) => index.add_entity_with_hash(hash, entity_id),
57            Self::ValueCountIndex(index) => {
58                index.add_entity_with_hash(hash, entity_id);
59            }
60        }
61    }
62
63    pub fn remove_entity_with_hash(&mut self, hash: HashValueType, entity_id: EntityId<E>) {
64        match self {
65            Self::Unindexed => {}
66            Self::FullIndex(index) => index.remove_entity_with_hash(hash, entity_id),
67            Self::ValueCountIndex(index) => {
68                index.remove_entity_with_hash(hash, entity_id);
69            }
70        }
71    }
72
73    pub fn get_index_set_with_hash(&self, hash: HashValueType) -> Option<&IndexSet<EntityId<E>>> {
74        match self {
75            Self::Unindexed => None,
76            Self::FullIndex(index) => index.get_with_hash(hash),
77            Self::ValueCountIndex(_) => None,
78        }
79    }
80
81    pub fn get_index_set_with_hash_result(&self, hash: HashValueType) -> IndexSetResult<'_, E> {
82        match self {
83            Self::Unindexed => IndexSetResult::<'_, E>::Unsupported,
84            Self::FullIndex(index) => match index.get_with_hash(hash) {
85                Some(set) => IndexSetResult::Set(set),
86                None => IndexSetResult::Empty,
87            },
88            Self::ValueCountIndex(_) => IndexSetResult::<'_, E>::Unsupported,
89        }
90    }
91
92    pub fn get_index_count_with_hash_result(&self, hash: HashValueType) -> IndexCountResult {
93        match self {
94            Self::Unindexed => IndexCountResult::Unsupported,
95            Self::FullIndex(index) => {
96                let count = index.get_with_hash(hash).map_or(0, |set| set.len());
97                IndexCountResult::Count(count)
98            }
99            Self::ValueCountIndex(index) => {
100                IndexCountResult::Count(index.get_with_hash(hash).unwrap_or(0))
101            }
102        }
103    }
104
105    pub fn remove_entity(&mut self, value: &P::CanonicalValue, entity_id: EntityId<E>) {
106        match self {
107            Self::Unindexed => {}
108            Self::FullIndex(index) => index.remove_entity(value, entity_id),
109            Self::ValueCountIndex(index) => index.remove_entity(value, entity_id),
110        }
111    }
112
113    pub fn add_entity(&mut self, value: &P::CanonicalValue, entity_id: EntityId<E>) {
114        match self {
115            Self::Unindexed => {}
116            Self::FullIndex(index) => {
117                index.add_entity(value, entity_id);
118            }
119            Self::ValueCountIndex(index) => {
120                index.add_entity(value, entity_id);
121            }
122        }
123    }
124
125    /// Returns `None` if there is no index.
126    pub fn max_indexed(&self) -> Option<usize> {
127        match self {
128            Self::Unindexed => None,
129            Self::FullIndex(index) => Some(index.max_indexed),
130            Self::ValueCountIndex(index) => Some(index.max_indexed),
131        }
132    }
133
134    pub fn set_max_indexed(&mut self, max_indexed: usize) {
135        match self {
136            Self::Unindexed => {}
137            Self::FullIndex(index) => index.max_indexed = max_indexed,
138            Self::ValueCountIndex(index) => index.max_indexed = max_indexed,
139        }
140    }
141}