graph_api_simplegraph/index/
mod.rs1use crate::VertexId;
2use graph_api_lib::{Index, IndexType, Value};
3use paste::paste;
4use smallbox::SmallBox;
5use smallbox::space::S8;
6use std::any::TypeId;
7use std::ops::Deref;
8use std::ops::Range;
9use uuid::Uuid;
10
11mod full_text;
12mod hash;
13mod range;
14use std::ops::Bound;
15
16#[derive(Debug)]
17pub(crate) enum VertexIndexStorage {
18 FullTextString(full_text::FullTextIndex<u32>),
19 HashUuid(hash::HashIndex<Uuid, u32>),
20 HashString(hash::HashIndex<String, u32>),
21 HashUSize(hash::HashIndex<usize, u32>),
22 HashU128(hash::HashIndex<u128, u32>),
23 HashU64(hash::HashIndex<u64, u32>),
24 HashU32(hash::HashIndex<u32, u32>),
25 HashU16(hash::HashIndex<u16, u32>),
26 HashU8(hash::HashIndex<u8, u32>),
27 HashI128(hash::HashIndex<i128, u32>),
28 HashI64(hash::HashIndex<i64, u32>),
29 HashI32(hash::HashIndex<i32, u32>),
30 HashI16(hash::HashIndex<i16, u32>),
31 HashI8(hash::HashIndex<i8, u32>),
32 HashBool(hash::HashIndex<bool, u32>),
33 RangeUuid(range::RangeIndex<Uuid, u32>),
34 RangeString(range::RangeIndex<String, u32>),
35 RangeUSize(range::RangeIndex<usize, u32>),
36 RangeU128(range::RangeIndex<u128, u32>),
37 RangeU64(range::RangeIndex<u64, u32>),
38 RangeU32(range::RangeIndex<u32, u32>),
39 RangeU16(range::RangeIndex<u16, u32>),
40 RangeU8(range::RangeIndex<u8, u32>),
41 RangeI128(range::RangeIndex<i128, u32>),
42 RangeI64(range::RangeIndex<i64, u32>),
43 RangeI32(range::RangeIndex<i32, u32>),
44 RangeI16(range::RangeIndex<i16, u32>),
45 RangeI8(range::RangeIndex<i8, u32>),
46 RangeBool(range::RangeIndex<bool, u32>),
47}
48
49impl<T: Index> From<&T> for VertexIndexStorage {
50 fn from(index: &T) -> Self {
51 macro_rules! index {
52 ($ty:ty, $ident: ident) => {
53 paste! {
54 if index.ty() == TypeId::of::<$ty>() {
55 match index.index_type() {
56 IndexType::FullText => {
57 return VertexIndexStorage::FullTextString(Default::default());
58 }
59 IndexType::Range => {
60 return VertexIndexStorage::[<Range $ident>](Default::default());
61 }
62 IndexType::Hash => {
63 return VertexIndexStorage::[<Hash $ident>](Default::default());
64 },
65 _=>{}
66 }
67 }
68 }
69 };
70 }
71 index!(String, String);
72 index!(Uuid, Uuid);
73 index!(usize, USize);
74 index!(u128, U128);
75 index!(u64, U64);
76 index!(u32, U32);
77 index!(u16, U16);
78 index!(u8, U8);
79 index!(i128, I128);
80 index!(i64, I64);
81 index!(i32, I32);
82 index!(i16, I16);
83 index!(i8, I8);
84 index!(bool, Bool);
85 panic!("unsupported index type {:?}", index)
86 }
87}
88
89impl VertexIndexStorage {
90 pub(crate) fn insert<I: Index>(&mut self, key: Value, value: u32, index: &I) {
91 macro_rules! insert {
92 ($ty: ident) => {
93 insert!($ty, $ty, into)
94 };
95 ($ty: ident, $index: ident, $conversion: expr) => {
96 paste! {
97 match (&key, index.index_type()) {
98 (Value::Str(key), IndexType::FullText) => {
99 if let VertexIndexStorage::FullTextString(index) = self {
100 index.insert(value, key);
101 return
102 }
103 },
104 (Value::$ty(key), IndexType::Range) => {
105 if let VertexIndexStorage::[<Range $index>](index) = self {
106 index.insert((*key).$conversion(), value);
107 return
108 }
109 },
110 (Value::$ty(key), IndexType::Hash) => {
111 if let VertexIndexStorage::[<Hash $index>](index) = self {
112 index.insert((*key).$conversion(), value);
113 return
114 }
115 },
116 _=>{}
117 }
118 }
119 };
120 }
121 insert!(Str, String, to_string);
122 insert!(USize);
123 insert!(U128);
124 insert!(U64);
125 insert!(U32);
126 insert!(U16);
127 insert!(U8);
128 insert!(I128);
129 insert!(I64);
130 insert!(I32);
131 insert!(I16);
132 insert!(I8);
133 insert!(Bool);
134 insert!(Uuid);
135 panic!("unsupported index type {:?}({})", index, index.index_type())
136 }
137 pub(crate) fn remove<I: Index>(&mut self, key: &Value, value: u32, index: &I) {
138 macro_rules! remove {
139 ($ty: ident) => {
140 remove!($ty, $ty)
141 };
142 ($ty: ident, $index: ident) => {
143 paste! {
144 if let Value::$ty(key) = key {
145 let key = key.deref();
146 match index.index_type() {
147 IndexType::FullText => {
148 if let VertexIndexStorage::FullTextString(index) = self {
149 index.remove(&value);
150 }
151 },
152 IndexType::Range => {
153 if let VertexIndexStorage::[<Range $index>](index) = self {
154 index.remove(key, &value);
155 }
156 },
157 IndexType::Hash => {
158 if let VertexIndexStorage::[<Hash $index>](index) = self {
159 index.remove(key, &value);
160 }
161 }
162 _=>{}
163 }
164 return;
165 }
166 }
167 };
168 }
169
170 remove!(Str, String);
171 remove!(USize);
172 remove!(U128);
173 remove!(U64);
174 remove!(U32);
175 remove!(U16);
176 remove!(U8);
177 remove!(I128);
178 remove!(I64);
179 remove!(I32);
180 remove!(I16);
181 remove!(I8);
182 remove!(Bool);
183 remove!(Uuid);
184 panic!("unsupported index type {:?}", index)
185 }
186
187 pub(crate) fn get<'a, I: Index>(
188 &'a self,
189 key: &Value,
190 index: &I,
191 ) -> SmallBox<dyn Iterator<Item = VertexId> + 'a, S8> {
192 let label = 0;
193 macro_rules! search {
194 ($ident: ident) => {
195 search!($ident, $ident);
196 };
197 ($ty: ident, $index: ident) => {
198 paste! {
199 match (key, index.index_type()) {
200 (Value::Str(key), IndexType::FullText) => {
201 let key = key.deref();
202 if let VertexIndexStorage::FullTextString(index) = self {
203 return smallbox::smallbox!(index.search(key).map(move |id| VertexId::new(label, id)));
204 }
205 },
206 (Value::$ty(key), IndexType::Range) => {
207 let key = key.deref();
208 if let VertexIndexStorage::[<Range $index>](index) = self {
209 return smallbox::smallbox!(index.get(key).map(move |id| VertexId::new(label, id)));
210 }
211 },
212 (Value::$ty(key), IndexType::Hash) => {
213 let key = key.deref();
214 if let VertexIndexStorage::[<Hash $index>](index) = self {
215 return smallbox::smallbox!(index.get(key).map(move |id| VertexId::new(label, id)));
216 }
217 },
218 _=>{}
219 }
220 }
221 };
222 }
223 search!(Str, String);
224 search!(USize);
225 search!(U128);
226 search!(U64);
227 search!(U32);
228 search!(U16);
229 search!(U8);
230 search!(I128);
231 search!(I64);
232 search!(I32);
233 search!(I16);
234 search!(I8);
235 search!(Bool);
236 search!(Uuid);
237 panic!("unsupported index type {:?}", index)
238 }
239
240 pub(crate) fn range<'a, I: Index>(
241 &'a self,
242 range: &Range<Value>,
243 index: &I,
244 ) -> SmallBox<dyn Iterator<Item = VertexId> + 'a, S8> {
245 let label = 0;
246 macro_rules! search {
247 ($ident: ident) => {
248 paste! {
249 search!($ident, [<$ident:lower>], $ident);
250 }
251 };
252 ($ident: ident, $ty: ty) => {
253 search!($ident, $ty, $ident);
254 };
255 ($ident: ident, $ty: ty, $index: ident) => {
256 paste! {
257 if let (Value::$ident(start), Value::$ident(end)) = (&range.start, &range.end) {
258 if let VertexIndexStorage::[<Range $index>](index) = self {
259 return smallbox::smallbox!(index.range::<$ty,_ >((Bound::Included(*start), Bound::Excluded(*end))).map(move |id| VertexId::new(label, id)));
260 }
261 }
262 }
263 };
264 }
265 search!(Str, str, String);
266 search!(USize);
267 search!(U128);
268 search!(U64);
269 search!(U32);
270 search!(U16);
271 search!(U8);
272 search!(I128);
273 search!(I64);
274 search!(I32);
275 search!(I16);
276 search!(I8);
277 search!(Bool);
278 panic!("unsupported index type {:?}", index)
279 }
280}