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}