raphtory_api/core/entities/
mod.rs1use super::input::input_node::parse_u64_strict;
2use bytemuck::{Pod, Zeroable};
3use edges::edge_ref::EdgeRef;
4use num_traits::ToPrimitive;
5use rayon::prelude::*;
6use serde::{Deserialize, Serialize};
7use std::{
8    borrow::Cow,
9    fmt::{Display, Formatter},
10    sync::Arc,
11};
12
13pub mod edges;
14pub mod properties;
15
16#[repr(transparent)]
18#[derive(
19    Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Deserialize, Serialize, Pod, Zeroable,
20)]
21pub struct VID(pub usize);
22
23impl Default for VID {
24    fn default() -> Self {
25        VID(usize::MAX)
26    }
27}
28
29impl VID {
30    pub fn index(&self) -> usize {
31        self.0
32    }
33
34    pub fn as_u64(&self) -> u64 {
35        self.0 as u64
36    }
37}
38
39impl From<usize> for VID {
40    fn from(id: usize) -> Self {
41        VID(id)
42    }
43}
44
45impl From<VID> for usize {
46    fn from(id: VID) -> Self {
47        id.0
48    }
49}
50
51#[repr(transparent)]
52#[derive(
53    Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Deserialize, Serialize, Pod, Zeroable,
54)]
55pub struct EID(pub usize);
56
57impl Default for EID {
58    fn default() -> Self {
59        EID(usize::MAX)
60    }
61}
62
63impl EID {
64    pub fn as_u64(self) -> u64 {
65        self.0 as u64
66    }
67}
68
69impl From<EID> for usize {
70    fn from(id: EID) -> Self {
71        id.0
72    }
73}
74
75impl From<usize> for EID {
76    fn from(id: usize) -> Self {
77        EID(id)
78    }
79}
80
81impl EID {
82    pub fn from_u64(id: u64) -> Self {
83        EID(id as usize)
84    }
85}
86
87#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
88pub enum GID {
89    U64(u64),
90    Str(String),
91}
92impl PartialEq<str> for GID {
93    fn eq(&self, other: &str) -> bool {
94        match self {
95            GID::U64(_) => false,
96            GID::Str(id) => id == other,
97        }
98    }
99}
100
101impl PartialEq<String> for GID {
102    fn eq(&self, other: &String) -> bool {
103        match self {
104            GID::U64(_) => false,
105            GID::Str(id) => id == other,
106        }
107    }
108}
109
110impl PartialEq<u64> for GID {
111    fn eq(&self, other: &u64) -> bool {
112        match self {
113            GID::Str(_) => false,
114            GID::U64(id) => id == other,
115        }
116    }
117}
118
119impl Default for GID {
120    fn default() -> Self {
121        GID::U64(u64::MAX)
122    }
123}
124
125impl Display for GID {
126    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
127        match self {
128            GID::U64(v) => write!(f, "{}", v),
129            GID::Str(v) => write!(f, "{}", v),
130        }
131    }
132}
133
134impl GID {
135    pub fn dtype(&self) -> GidType {
136        match self {
137            GID::U64(_) => GidType::U64,
138            GID::Str(_) => GidType::Str,
139        }
140    }
141    pub fn into_str(self) -> Option<String> {
142        match self {
143            GID::Str(v) => Some(v),
144            _ => None,
145        }
146    }
147
148    pub fn into_u64(self) -> Option<u64> {
149        match self {
150            GID::U64(v) => Some(v),
151            _ => None,
152        }
153    }
154
155    pub fn as_str(&self) -> Option<&str> {
156        match self {
157            GID::Str(v) => Some(v.as_str()),
158            _ => None,
159        }
160    }
161
162    pub fn as_u64(&self) -> Option<u64> {
163        match self {
164            GID::U64(v) => Some(*v),
165            _ => None,
166        }
167    }
168
169    pub fn to_str(&self) -> Cow<str> {
170        match self {
171            GID::U64(v) => Cow::Owned(v.to_string()),
172            GID::Str(v) => Cow::Borrowed(v),
173        }
174    }
175
176    pub fn to_i64(&self) -> Option<i64> {
177        match self {
178            GID::U64(v) => v.to_i64(),
179            GID::Str(v) => parse_u64_strict(v)?.to_i64(),
180        }
181    }
182
183    pub fn to_u64(&self) -> Option<u64> {
184        match self {
185            GID::U64(v) => Some(*v),
186            GID::Str(v) => parse_u64_strict(v),
187        }
188    }
189
190    pub fn as_ref(&self) -> GidRef {
191        match self {
192            GID::U64(v) => GidRef::U64(*v),
193            GID::Str(v) => GidRef::Str(v),
194        }
195    }
196}
197
198impl From<u64> for GID {
199    fn from(id: u64) -> Self {
200        Self::U64(id)
201    }
202}
203
204impl From<String> for GID {
205    fn from(id: String) -> Self {
206        Self::Str(id)
207    }
208}
209
210impl From<&str> for GID {
211    fn from(id: &str) -> Self {
212        Self::Str(id.to_string())
213    }
214}
215
216impl<'a> From<GidRef<'a>> for GID {
217    fn from(value: GidRef<'a>) -> Self {
218        match value {
219            GidRef::U64(v) => GID::U64(v),
220            GidRef::Str(v) => GID::Str(v.to_owned()),
221        }
222    }
223}
224
225#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
226pub enum GidRef<'a> {
227    U64(u64),
228    Str(&'a str),
229}
230
231#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
232pub enum GidType {
233    U64,
234    Str,
235}
236
237impl Display for GidType {
238    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
239        match self {
240            GidType::U64 => {
241                write!(f, "Numeric")
242            }
243            GidType::Str => {
244                write!(f, "String")
245            }
246        }
247    }
248}
249
250impl Display for GidRef<'_> {
251    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
252        match self {
253            GidRef::U64(v) => write!(f, "{}", v),
254            GidRef::Str(v) => write!(f, "{}", v),
255        }
256    }
257}
258
259impl<'a> From<&'a GID> for GidRef<'a> {
260    fn from(value: &'a GID) -> Self {
261        match value {
262            GID::U64(v) => GidRef::U64(*v),
263            GID::Str(v) => GidRef::Str(v),
264        }
265    }
266}
267
268impl<'a> GidRef<'a> {
269    pub fn dtype(self) -> GidType {
270        match self {
271            GidRef::U64(_) => GidType::U64,
272            GidRef::Str(_) => GidType::Str,
273        }
274    }
275    pub fn as_str(self) -> Option<&'a str> {
276        match self {
277            GidRef::Str(s) => Some(s),
278            _ => None,
279        }
280    }
281
282    pub fn as_u64(self) -> Option<u64> {
283        match self {
284            GidRef::U64(v) => Some(v),
285            _ => None,
286        }
287    }
288
289    pub fn to_owned(self) -> GID {
290        match self {
291            GidRef::U64(v) => GID::U64(v),
292            GidRef::Str(v) => GID::Str(v.to_owned()),
293        }
294    }
295
296    pub fn to_str(self) -> Cow<'a, str> {
297        match self {
298            GidRef::U64(v) => Cow::Owned(v.to_string()),
299            GidRef::Str(v) => Cow::Borrowed(v),
300        }
301    }
302
303    pub fn to_i64(self) -> Option<i64> {
304        match self {
305            GidRef::U64(v) => v.to_i64(),
306            GidRef::Str(v) => parse_u64_strict(v)?.to_i64(),
307        }
308    }
309
310    pub fn to_u64(self) -> Option<u64> {
311        match self {
312            GidRef::U64(v) => Some(v),
313            GidRef::Str(v) => parse_u64_strict(v),
314        }
315    }
316}
317
318#[derive(Clone, Debug)]
319pub enum LayerIds {
320    None,
321    All,
322    One(usize),
323    Multiple(Multiple),
324}
325
326#[derive(Clone, Debug, Default)]
327pub struct Multiple(pub Arc<[usize]>);
328
329impl Multiple {
330    #[inline]
331    pub fn binary_search(&self, pos: &usize) -> Option<usize> {
332        self.0.binary_search(pos).ok()
333    }
334
335    #[inline]
336    pub fn into_iter(&self) -> impl Iterator<Item = usize> {
337        let ids = self.0.clone();
338        (0..ids.len()).map(move |i| ids[i])
339    }
340
341    #[inline]
342    pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
343        self.0.iter().copied()
344    }
345
346    #[inline]
347    pub fn find(&self, id: usize) -> Option<usize> {
348        self.0.get(id).copied()
349    }
350
351    #[inline]
352    pub fn par_iter(&self) -> impl rayon::iter::ParallelIterator<Item = usize> {
353        let bit_vec = self.0.clone();
354        (0..bit_vec.len()).into_par_iter().map(move |i| bit_vec[i])
355    }
356
357    #[inline]
358    pub fn len(&self) -> usize {
359        self.0.len()
360    }
361}
362
363impl FromIterator<usize> for Multiple {
364    fn from_iter<I: IntoIterator<Item = usize>>(iter: I) -> Self {
365        Multiple(iter.into_iter().collect())
366    }
367}
368
369impl From<Vec<usize>> for Multiple {
370    fn from(v: Vec<usize>) -> Self {
371        v.into_iter().collect()
372    }
373}
374
375#[cfg(test)]
376mod test {
377    use crate::core::entities::Multiple;
378
379    #[test]
380    fn empty_bit_multiple() {
381        let bm = super::Multiple::default();
382        let actual = bm.into_iter().collect::<Vec<_>>();
383        let expected: Vec<usize> = vec![];
384        assert_eq!(actual, expected);
385    }
386
387    #[test]
388    fn set_one() {
389        let bm: Multiple = [1].into_iter().collect();
390        let actual = bm.into_iter().collect::<Vec<_>>();
391        assert_eq!(actual, vec![1usize]);
392    }
393
394    #[test]
395    fn set_two() {
396        let bm: Multiple = [1, 67].into_iter().collect();
397
398        let actual = bm.into_iter().collect::<Vec<_>>();
399        assert_eq!(actual, vec![1usize, 67]);
400    }
401}
402
403impl LayerIds {
404    pub fn find(&self, layer_id: usize) -> Option<usize> {
405        match self {
406            LayerIds::All => Some(layer_id),
407            LayerIds::One(id) => {
408                if *id == layer_id {
409                    Some(layer_id)
410                } else {
411                    None
412                }
413            }
414            LayerIds::Multiple(ids) => ids.binary_search(&layer_id).map(|_| layer_id),
415            LayerIds::None => None,
416        }
417    }
418
419    pub fn intersect(&self, other: &LayerIds) -> LayerIds {
420        match (self, other) {
421            (LayerIds::None, _) => LayerIds::None,
422            (_, LayerIds::None) => LayerIds::None,
423            (LayerIds::All, other) => other.clone(),
424            (this, LayerIds::All) => this.clone(),
425            (LayerIds::One(id), other) => {
426                if other.contains(id) {
427                    LayerIds::One(*id)
428                } else {
429                    LayerIds::None
430                }
431            }
432            (LayerIds::Multiple(ids), other) => {
433                let ids: Vec<usize> = ids.iter().filter(|id| other.contains(id)).collect();
434                match ids.len() {
435                    0 => LayerIds::None,
436                    1 => LayerIds::One(ids[0]),
437                    _ => LayerIds::Multiple(ids.into()),
438                }
439            }
440        }
441    }
442
443    pub fn constrain_from_edge(&self, e: EdgeRef) -> Cow<LayerIds> {
444        match e.layer() {
445            None => Cow::Borrowed(self),
446            Some(l) => self
447                .find(l)
448                .map(|id| Cow::Owned(LayerIds::One(id)))
449                .unwrap_or(Cow::Owned(LayerIds::None)),
450        }
451    }
452
453    pub fn contains(&self, layer_id: &usize) -> bool {
454        self.find(*layer_id).is_some()
455    }
456
457    pub fn is_none(&self) -> bool {
458        matches!(self, LayerIds::None)
459    }
460}
461
462impl From<Vec<usize>> for LayerIds {
463    fn from(mut v: Vec<usize>) -> Self {
464        match v.len() {
465            0 => LayerIds::All,
466            1 => LayerIds::One(v[0]),
467            _ => {
468                v.sort_unstable();
469                v.dedup();
470                LayerIds::Multiple(v.into())
471            }
472        }
473    }
474}
475
476impl<const N: usize> From<[usize; N]> for LayerIds {
477    fn from(v: [usize; N]) -> Self {
478        match v.len() {
479            0 => LayerIds::All,
480            1 => LayerIds::One(v[0]),
481            _ => {
482                let mut v = v.to_vec();
483                v.sort_unstable();
484                v.dedup();
485                LayerIds::Multiple(v.into())
486            }
487        }
488    }
489}
490
491impl From<usize> for LayerIds {
492    fn from(id: usize) -> Self {
493        LayerIds::One(id)
494    }
495}