Skip to main content

indexset/cdc/
change.rs

1#[cfg(feature = "multimap")]
2use {crate::core::multipair::OrdMultiPair, crate::core::pair::Pair};
3
4/// Unique event identifier.
5///
6/// For any two events `event1` and `event2`, if `event1` should be applied before
7/// `event2`, then `event1.id()` should be less than `event2.id()`.
8#[derive(Copy, Clone, Debug, Default, Ord, PartialOrd, Eq, PartialEq)]
9pub struct Id(u64);
10
11impl Id {
12    pub fn inner(&self) -> u64 {
13        self.0
14    }
15
16    pub fn is_next_for(&self, other: Id) -> bool {
17        self.0 == other.0 + 1
18    }
19}
20
21impl From<u64> for Id {
22    fn from(value: u64) -> Self {
23        Self(value)
24    }
25}
26
27impl From<Id> for u64 {
28    fn from(id: Id) -> Self {
29        id.0
30    }
31}
32
33#[derive(Debug, Clone)]
34pub enum ChangeEvent<T> {
35    /// Describes value insert event.
36    InsertAt {
37        event_id: Id,
38        /// Max value that is used to identify node to remove value in.
39        max_value: T,
40        /// Value that is inserted itself.
41        value: T,
42        /// Index of a place in array to insert a value in.
43        index: usize,
44    },
45    /// Describes value remove event.
46    RemoveAt {
47        event_id: Id,
48        /// Max value that is used to identify node to remove value from.
49        max_value: T,
50        /// Value that is removed itself.
51        value: T,
52        /// Index of a place in array to remove a value from.
53        index: usize,
54    },
55    /// Describes node creation event.
56    CreateNode {
57        event_id: Id,
58        /// Initial max value.
59        max_value: T,
60    },
61    /// Describes node removal event.
62    RemoveNode {
63        event_id: Id,
64        /// Max value that is used to identify removed node.
65        max_value: T,
66    },
67    /// Describes node split event.
68    SplitNode {
69        event_id: Id,
70        /// Max value that is used to identify node to split.
71        max_value: T,
72        /// Index of a value that will be last value in first split part.
73        split_index: usize,
74    },
75}
76
77impl<T> ChangeEvent<T> {
78    pub fn id(&self) -> Id {
79        match self {
80            ChangeEvent::InsertAt { event_id, .. } => *event_id,
81            ChangeEvent::RemoveAt { event_id, .. } => *event_id,
82            ChangeEvent::CreateNode { event_id, .. } => *event_id,
83            ChangeEvent::RemoveNode { event_id, .. } => *event_id,
84            ChangeEvent::SplitNode { event_id, .. } => *event_id,
85        }
86    }
87}
88
89/// A [`ChangeEvent`] that has not yet been assigned an event [`Id`].
90///
91/// This type is used to defer event [`Id`] allocation until after an operation
92/// successfully commits, ensuring no gaps in event [`Id`]a.
93#[derive(Debug, Clone)]
94pub enum ChangeEventUnassigned<T> {
95    /// Unassigned [`ChangeEvent::InsertAt`].
96    InsertAt { max_value: T, value: T, index: usize },
97    /// Unassigned [`ChangeEvent::RemoveAt`].
98    RemoveAt { max_value: T, value: T, index: usize },
99    /// Unassigned [`ChangeEvent::CreateNode`].
100    CreateNode { max_value: T },
101    /// Unassigned [`ChangeEvent::RemoveNode`].
102    RemoveNode { max_value: T },
103    /// Unassigned [`ChangeEvent::SplitNode`].
104    SplitNode { max_value: T, split_index: usize },
105}
106
107impl<T> ChangeEventUnassigned<T> {
108    /// Assign an event [`Id`] to this unassigned event, converting it to a [`ChangeEvent`].
109    pub fn assign_id(self, event_id: Id) -> ChangeEvent<T> {
110        match self {
111            Self::InsertAt {
112                max_value,
113                value,
114                index,
115            } => ChangeEvent::InsertAt {
116                event_id,
117                max_value,
118                value,
119                index,
120            },
121            Self::RemoveAt {
122                max_value,
123                value,
124                index,
125            } => ChangeEvent::RemoveAt {
126                event_id,
127                max_value,
128                value,
129                index,
130            },
131            Self::CreateNode { max_value } => ChangeEvent::CreateNode { event_id, max_value },
132            Self::RemoveNode { max_value } => ChangeEvent::RemoveNode { event_id, max_value },
133            Self::SplitNode { max_value, split_index } => ChangeEvent::SplitNode {
134                event_id,
135                max_value,
136                split_index,
137            },
138        }
139    }
140}
141
142#[cfg(feature = "multimap")]
143fn multipair_change_event_into_pair<K, V, M>(ev: ChangeEvent<M>) -> ChangeEvent<Pair<K, V>>
144where
145    M: Into<Pair<K, V>>,
146{
147    match ev {
148        ChangeEvent::InsertAt {
149            event_id,
150            max_value,
151            value,
152            index,
153        } => ChangeEvent::InsertAt {
154            event_id,
155            max_value: max_value.into(),
156            value: value.into(),
157            index,
158        },
159        ChangeEvent::RemoveAt {
160            event_id,
161            max_value,
162            value,
163            index,
164        } => ChangeEvent::RemoveAt {
165            event_id,
166            max_value: max_value.into(),
167            value: value.into(),
168            index,
169        },
170        ChangeEvent::CreateNode { event_id, max_value } => ChangeEvent::CreateNode {
171            event_id,
172            max_value: max_value.into(),
173        },
174        ChangeEvent::RemoveNode { event_id, max_value } => ChangeEvent::RemoveNode {
175            event_id,
176            max_value: max_value.into(),
177        },
178        ChangeEvent::SplitNode {
179            event_id,
180            max_value,
181            split_index,
182        } => ChangeEvent::SplitNode {
183            event_id,
184            max_value: max_value.into(),
185            split_index,
186        },
187    }
188}
189
190#[cfg(feature = "multimap")]
191impl<K, V> From<ChangeEvent<OrdMultiPair<K, V>>> for ChangeEvent<Pair<K, V>> {
192    fn from(ev: ChangeEvent<OrdMultiPair<K, V>>) -> Self {
193        multipair_change_event_into_pair(ev)
194    }
195}