pijul_core/pristine/
edge.rs1use super::L64;
2use super::change_id::*;
3use super::vertex::*;
4
5bitflags! {
6 #[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
8 pub struct EdgeFlags: u8 {
9 const BLOCK = 1;
10 const PSEUDO = 4;
13 const FOLDER = 16;
15 const PARENT = 32;
17 const DELETED = 128;
20 }
21}
22
23impl EdgeFlags {
24 #[inline]
25 pub(crate) fn df() -> Self {
26 Self::DELETED | Self::FOLDER
27 }
28
29 #[inline]
30 pub(crate) fn pseudof() -> Self {
31 Self::PSEUDO | Self::FOLDER
32 }
33
34 #[inline]
35 pub(crate) fn alive_children() -> Self {
36 Self::BLOCK | Self::PSEUDO | Self::FOLDER
37 }
38
39 #[inline]
40 pub(crate) fn parent_folder() -> Self {
41 Self::PARENT | Self::FOLDER
42 }
43
44 #[inline]
45 pub fn is_deleted(&self) -> bool {
46 self.contains(EdgeFlags::DELETED)
47 }
48
49 #[inline]
50 pub fn is_alive_parent(&self) -> bool {
51 *self & (EdgeFlags::DELETED | EdgeFlags::PARENT) == EdgeFlags::PARENT
52 }
53 #[inline]
54 pub fn is_parent(&self) -> bool {
55 self.contains(EdgeFlags::PARENT)
56 }
57 #[inline]
58 pub fn is_folder(&self) -> bool {
59 self.contains(EdgeFlags::FOLDER)
60 }
61 #[inline]
62 pub fn is_block(&self) -> bool {
63 self.contains(EdgeFlags::BLOCK)
64 }
65}
66
67#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
69#[doc(hidden)]
70pub struct Edge {
71 pub flag: EdgeFlags,
73 pub dest: Position<ChangeId>,
75 pub introduced_by: ChangeId,
79}
80
81#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
83pub struct SerializedEdge([super::L64; 3]);
84
85impl std::fmt::Debug for SerializedEdge {
86 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
87 let pos = self.dest();
88 use super::Base32;
89 write!(
90 fmt,
91 "E({:?}, {}[{}], {})",
92 self.flag(),
93 pos.change.to_base32(),
94 (pos.pos.0).0,
95 self.introduced_by().to_base32()
96 )
97 }
98}
99
100impl std::ops::SubAssign<EdgeFlags> for SerializedEdge {
101 fn sub_assign(&mut self, e: EdgeFlags) {
102 let f = &mut (self.0)[0];
103 f.0 = ((u64::from_le(f.0)) & !((e.bits() as u64) << 56)).to_le()
104 }
105}
106
107impl SerializedEdge {
108 pub fn flag(&self) -> EdgeFlags {
109 let f = u64::from_le((self.0)[0].0);
110 EdgeFlags::from_bits((f >> 56) as u8).unwrap()
111 }
112 pub fn dest(&self) -> Position<ChangeId> {
113 let pos = u64::from_le((self.0[0]).0);
114 Position {
115 change: ChangeId((self.0)[1]),
116 pos: ChangePosition(L64((pos & 0xffffffffffffff).to_le())),
117 }
118 }
119 pub fn introduced_by(&self) -> ChangeId {
120 ChangeId((self.0)[2])
121 }
122}
123
124impl From<SerializedEdge> for Edge {
125 fn from(s: SerializedEdge) -> Edge {
126 Edge {
127 flag: s.flag(),
128 dest: s.dest(),
129 introduced_by: s.introduced_by(),
130 }
131 }
132}
133
134impl From<Edge> for SerializedEdge {
135 fn from(s: Edge) -> SerializedEdge {
136 let pos = u64::from_le((s.dest.pos.0).0);
137 assert!(pos < 1 << 56);
138 SerializedEdge([
139 (((s.flag.bits() as u64) << 56) | pos).into(),
140 s.dest.change.0,
141 s.introduced_by.0,
142 ])
143 }
144}
145
146impl<'a> From<&'a SerializedEdge> for Edge {
147 fn from(s: &'a SerializedEdge) -> Edge {
148 Edge {
149 flag: s.flag(),
150 dest: s.dest(),
151 introduced_by: s.introduced_by(),
152 }
153 }
154}
155impl SerializedEdge {
156 pub fn empty(dest: Position<ChangeId>, intro: ChangeId) -> Self {
157 SerializedEdge([dest.pos.0, dest.change.0, intro.0])
158 }
159
160 pub fn new(flag: EdgeFlags, change: ChangeId, pos: ChangePosition, intro: ChangeId) -> Self {
161 let pos = pos.0.as_u64();
162 assert!(pos < 1 << 56);
163 SerializedEdge([
164 (pos | ((flag.bits() as u64) << 56)).into(),
165 change.0,
166 intro.0,
167 ])
168 }
169}