loro_ffi/
version.rs

1use std::{cmp::Ordering, collections::HashMap, sync::RwLock};
2
3use loro::{IdSpan, LoroResult, PeerID, ID};
4
5use crate::CounterSpan;
6
7pub struct VersionVector(RwLock<loro::VersionVector>);
8
9impl Default for VersionVector {
10    fn default() -> Self {
11        Self::new()
12    }
13}
14
15impl VersionVector {
16    pub fn new() -> Self {
17        Self(RwLock::new(loro::VersionVector::default()))
18    }
19
20    pub fn diff(&self, rhs: &Self) -> VersionVectorDiff {
21        self.0.read().unwrap().diff(&rhs.0.read().unwrap()).into()
22    }
23
24    pub fn get_last(&self, peer: PeerID) -> Option<i32> {
25        self.0.read().unwrap().get_last(peer)
26    }
27
28    pub fn set_last(&self, id: ID) {
29        self.0.write().unwrap().set_last(id);
30    }
31
32    pub fn set_end(&self, id: ID) {
33        self.0.write().unwrap().set_end(id);
34    }
35
36    pub fn get_missing_span(&self, target: &Self) -> Vec<IdSpan> {
37        self.0
38            .read()
39            .unwrap()
40            .get_missing_span(&target.0.read().unwrap())
41    }
42
43    pub fn merge(&self, other: &VersionVector) {
44        self.0.write().unwrap().merge(&other.0.read().unwrap())
45    }
46
47    pub fn includes_vv(&self, other: &VersionVector) -> bool {
48        self.0.read().unwrap().includes_vv(&other.0.read().unwrap())
49    }
50
51    pub fn includes_id(&self, id: ID) -> bool {
52        self.0.read().unwrap().includes_id(id)
53    }
54
55    pub fn intersect_span(&self, target: IdSpan) -> Option<CounterSpan> {
56        self.0.read().unwrap().intersect_span(target)
57    }
58
59    pub fn extend_to_include_vv(&self, other: &VersionVector) {
60        self.0
61            .write()
62            .unwrap()
63            .extend_to_include_vv(other.0.read().unwrap().iter());
64    }
65
66    pub fn partial_cmp(&self, other: &VersionVector) -> Option<Ordering> {
67        self.0.read().unwrap().partial_cmp(&other.0.read().unwrap())
68    }
69
70    pub fn encode(&self) -> Vec<u8> {
71        self.0.read().unwrap().encode()
72    }
73
74    pub fn decode(bytes: &[u8]) -> LoroResult<Self> {
75        let ans = Self(RwLock::new(loro::VersionVector::decode(bytes)?));
76        Ok(ans)
77    }
78
79    pub fn to_hashmap(&self) -> HashMap<u64, i32> {
80        self.0
81            .read()
82            .unwrap()
83            .iter()
84            .map(|(id, version)| (*id, *version))
85            .collect()
86    }
87
88    pub fn try_update_last(&self, id: ID) -> bool {
89        self.0.write().unwrap().try_update_last(id)
90    }
91}
92
93impl PartialEq for VersionVector {
94    fn eq(&self, other: &Self) -> bool {
95        self.0.read().unwrap().eq(&other.0.read().unwrap())
96    }
97}
98
99impl Eq for VersionVector {}
100
101#[derive(Debug)]
102pub struct Frontiers(loro::Frontiers);
103
104impl Frontiers {
105    pub fn new() -> Self {
106        Self(loro::Frontiers::default())
107    }
108
109    pub fn from_id(id: ID) -> Self {
110        Self(loro::Frontiers::from(id))
111    }
112
113    pub fn from_ids(ids: Vec<ID>) -> Self {
114        Self(loro::Frontiers::from(ids))
115    }
116
117    pub fn encode(&self) -> Vec<u8> {
118        self.0.encode()
119    }
120
121    pub fn decode(bytes: &[u8]) -> LoroResult<Self> {
122        let ans = Self(loro::Frontiers::decode(bytes)?);
123        Ok(ans)
124    }
125
126    pub fn is_empty(&self) -> bool {
127        self.0.is_empty()
128    }
129
130    pub fn to_vec(&self) -> Vec<ID> {
131        self.0.to_vec()
132    }
133}
134
135impl PartialEq for Frontiers {
136    fn eq(&self, other: &Self) -> bool {
137        self.0.eq(&other.0)
138    }
139}
140
141impl Eq for Frontiers {}
142
143impl Default for Frontiers {
144    fn default() -> Self {
145        Self::new()
146    }
147}
148
149pub struct VersionVectorDiff {
150    /// need to add these spans to move from right to left
151    pub retreat: HashMap<PeerID, CounterSpan>,
152    /// need to add these spans to move from left to right
153    pub forward: HashMap<PeerID, CounterSpan>,
154}
155
156pub struct VersionRangeItem {
157    pub peer: PeerID,
158    pub start: i32,
159    pub end: i32,
160}
161
162pub struct VersionRange(RwLock<loro::VersionRange>);
163
164impl VersionRange {
165    pub fn new() -> Self {
166        Self(RwLock::new(loro::VersionRange::new()))
167    }
168
169    pub fn from_vv(vv: &VersionVector) -> Self {
170        let loro_vv: loro::VersionVector = vv.into();
171        Self(RwLock::new(loro::VersionRange::from_vv(&loro_vv)))
172    }
173
174    pub fn clear(&self) {
175        self.0.write().unwrap().clear();
176    }
177
178    pub fn get(&self, peer: PeerID) -> Option<CounterSpan> {
179        self.0
180            .read()
181            .unwrap()
182            .get(&peer)
183            .map(|(start, end)| CounterSpan::new(*start, *end))
184    }
185
186    pub fn insert(&self, peer: PeerID, start: i32, end: i32) {
187        self.0.write().unwrap().insert(peer, start, end);
188    }
189
190    pub fn contains_ops_between(&self, vv_a: &VersionVector, vv_b: &VersionVector) -> bool {
191        let loro_vv_a: loro::VersionVector = vv_a.into();
192        let loro_vv_b: loro::VersionVector = vv_b.into();
193        self.0
194            .read()
195            .unwrap()
196            .contains_ops_between(&loro_vv_a, &loro_vv_b)
197    }
198
199    pub fn has_overlap_with(&self, span: IdSpan) -> bool {
200        self.0.read().unwrap().has_overlap_with(span)
201    }
202
203    pub fn contains_id(&self, id: ID) -> bool {
204        self.0.read().unwrap().contains_id(id)
205    }
206
207    pub fn contains_id_span(&self, span: IdSpan) -> bool {
208        self.0.read().unwrap().contains_id_span(span)
209    }
210
211    pub fn extends_to_include_id_span(&self, span: IdSpan) {
212        self.0.write().unwrap().extends_to_include_id_span(span);
213    }
214
215    pub fn is_empty(&self) -> bool {
216        self.0.read().unwrap().is_empty()
217    }
218
219    pub fn get_peers(&self) -> Vec<PeerID> {
220        self.0
221            .read()
222            .unwrap()
223            .iter()
224            .map(|(peer, _)| *peer)
225            .collect()
226    }
227
228    pub fn get_all_ranges(&self) -> Vec<VersionRangeItem> {
229        self.0
230            .read()
231            .unwrap()
232            .iter()
233            .map(|(peer, (start, end))| VersionRangeItem {
234                peer: *peer,
235                start: *start,
236                end: *end,
237            })
238            .collect()
239    }
240}
241
242impl Default for VersionRange {
243    fn default() -> Self {
244        Self::new()
245    }
246}
247
248impl From<loro::VersionRange> for VersionRange {
249    fn from(value: loro::VersionRange) -> Self {
250        Self(RwLock::new(value))
251    }
252}
253
254impl From<VersionRange> for loro::VersionRange {
255    fn from(value: VersionRange) -> Self {
256        value.0.into_inner().unwrap()
257    }
258}
259
260impl From<&VersionRange> for loro::VersionRange {
261    fn from(value: &VersionRange) -> Self {
262        value.0.read().unwrap().clone()
263    }
264}
265
266impl From<loro::VersionVectorDiff> for VersionVectorDiff {
267    fn from(value: loro::VersionVectorDiff) -> Self {
268        Self {
269            retreat: value.retreat.into_iter().collect(),
270            forward: value.forward.into_iter().collect(),
271        }
272    }
273}
274
275impl From<VersionVector> for loro::VersionVector {
276    fn from(value: VersionVector) -> Self {
277        value.0.into_inner().unwrap()
278    }
279}
280
281impl From<&VersionVector> for loro::VersionVector {
282    fn from(value: &VersionVector) -> Self {
283        value.0.read().unwrap().clone()
284    }
285}
286
287impl From<loro::VersionVector> for VersionVector {
288    fn from(value: loro::VersionVector) -> Self {
289        Self(RwLock::new(value))
290    }
291}
292
293impl From<loro::Frontiers> for Frontiers {
294    fn from(value: loro::Frontiers) -> Self {
295        Self(value)
296    }
297}
298
299impl From<Frontiers> for loro::Frontiers {
300    fn from(value: Frontiers) -> Self {
301        value.0
302    }
303}
304
305impl From<&Frontiers> for loro::Frontiers {
306    fn from(value: &Frontiers) -> Self {
307        value.0.clone()
308    }
309}