graph_api_simplegraph/index/
mod.rs

1use 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}