Skip to main content

automerge/columnar/column_range/
obj_id.rs

1use std::{convert::Infallible, ops::Range};
2
3use crate::{
4    columnar::{
5        encoding::{raw, DecodeColumnError, RleDecoder, RleEncoder, Sink},
6        SpliceError,
7    },
8    convert,
9    types::{ObjId, OpId},
10};
11
12use super::RleRange;
13
14#[derive(Debug, Clone, PartialEq)]
15pub(crate) struct ObjIdRange {
16    actor: RleRange<u64>,
17    counter: RleRange<u64>,
18}
19
20impl ObjIdRange {
21    pub(crate) fn new(actor: RleRange<u64>, counter: RleRange<u64>) -> Option<Self> {
22        if actor.is_empty() || counter.is_empty() {
23            None
24        } else {
25            Some(Self { actor, counter })
26        }
27    }
28
29    pub(crate) fn actor_range(&self) -> &RleRange<u64> {
30        &self.actor
31    }
32
33    pub(crate) fn counter_range(&self) -> &RleRange<u64> {
34        &self.counter
35    }
36
37    pub(crate) fn encode<O, I: Iterator<Item = convert::ObjId<O>> + Clone>(
38        ids: I,
39        out: &mut Vec<u8>,
40    ) -> Option<Self>
41    where
42        O: convert::OpId<usize>,
43    {
44        // SAFETY: the incoming iterator is infallible and there are no existing elements
45        Self {
46            actor: (0..0).into(),
47            counter: (0..0).into(),
48        }
49        .splice::<_, Infallible, _>(&[], 0..0, ids.map(Ok), out)
50        .unwrap()
51    }
52
53    /// Given some existing columns of object IDs splice a new set of object IDs in with the
54    /// existing ones
55    ///
56    /// Note that this returns `None` if the resulting range is empty (which will only occur if the
57    /// replace range is larger than the input iterator and `ids` is an empty iterator).
58    pub(crate) fn splice<
59        O,
60        E: std::error::Error,
61        I: Iterator<Item = Result<convert::ObjId<O>, E>> + Clone,
62    >(
63        &self,
64        data: &[u8],
65        replace: Range<usize>,
66        ids: I,
67        out: &mut Vec<u8>,
68    ) -> Result<Option<Self>, SpliceError<raw::Error, E>>
69    where
70        O: convert::OpId<usize>,
71    {
72        let actor = self.actor.splice(
73            data,
74            replace.clone(),
75            ids.clone().map(|id| id.map(encoded_actor)),
76            out,
77        )?;
78
79        if actor.is_empty() {
80            return Ok(None);
81        }
82
83        let counter = self.counter.splice(
84            data,
85            replace,
86            ids.map(|i| {
87                i.map(|i| match i {
88                    convert::ObjId::Root => None,
89                    convert::ObjId::Op(o) => Some(o.counter()),
90                })
91            }),
92            out,
93        )?;
94
95        Ok(Some(Self { actor, counter }))
96    }
97
98    pub(crate) fn iter<'a>(&self, data: &'a [u8]) -> ObjIdIter<'a> {
99        ObjIdIter {
100            actor: self.actor.decoder(data),
101            counter: self.counter.decoder(data),
102        }
103    }
104}
105
106fn encoded_actor<O>(id: convert::ObjId<O>) -> Option<u64>
107where
108    O: convert::OpId<usize>,
109{
110    match id {
111        convert::ObjId::Root => None,
112        convert::ObjId::Op(o) => Some(o.actor() as u64),
113    }
114}
115
116#[derive(Clone)]
117pub(crate) struct ObjIdIter<'a> {
118    actor: RleDecoder<'a, u64>,
119    counter: RleDecoder<'a, u64>,
120}
121
122impl ObjIdIter<'_> {
123    fn try_next(&mut self) -> Result<Option<ObjId>, DecodeColumnError> {
124        let actor = self
125            .actor
126            .next()
127            .transpose()
128            .map_err(|e| DecodeColumnError::decode_raw("actor", e))?;
129        let counter = self
130            .counter
131            .next()
132            .transpose()
133            .map_err(|e| DecodeColumnError::decode_raw("counter", e))?;
134        match (actor, counter) {
135            (None | Some(None), None | Some(None)) => Ok(Some(ObjId::root())),
136            (Some(Some(a)), Some(Some(c))) => Ok(Some(ObjId(OpId::new(c, a as usize)))),
137            (_, Some(Some(0))) => Ok(Some(ObjId::root())),
138            (Some(None) | None, _) => Err(DecodeColumnError::unexpected_null("actor")),
139            (_, Some(None) | None) => Err(DecodeColumnError::unexpected_null("counter")),
140        }
141    }
142}
143
144impl Iterator for ObjIdIter<'_> {
145    type Item = Result<ObjId, DecodeColumnError>;
146
147    fn next(&mut self) -> Option<Self::Item> {
148        self.try_next().transpose()
149    }
150}
151
152pub(crate) struct ObjIdEncoder<S> {
153    actor: RleEncoder<S, u64>,
154    counter: RleEncoder<S, u64>,
155}
156
157impl<S: Sink> ObjIdEncoder<S> {
158    pub(crate) fn append<O>(&mut self, id: convert::ObjId<O>)
159    where
160        O: convert::OpId<usize>,
161    {
162        match id {
163            convert::ObjId::Root => {
164                self.actor.append_null();
165                self.counter.append_null();
166            }
167            convert::ObjId::Op(o) => {
168                self.actor.append_value(o.actor() as u64);
169                self.counter.append_value(o.counter());
170            }
171        }
172    }
173}
174
175impl ObjIdEncoder<Vec<u8>> {
176    pub(crate) fn new() -> Self {
177        Self {
178            actor: RleEncoder::from(Vec::new()),
179            counter: RleEncoder::from(Vec::new()),
180        }
181    }
182
183    pub(crate) fn finish(self, out: &mut Vec<u8>) -> Option<ObjIdRange> {
184        let start = out.len();
185        let (actor, _) = self.actor.finish();
186        out.extend(actor);
187        let actor_end = out.len();
188
189        let (counter, _) = self.counter.finish();
190        out.extend(counter);
191        let counter_end = out.len();
192
193        if start == counter_end {
194            None
195        } else {
196            Some(ObjIdRange {
197                actor: (start..actor_end).into(),
198                counter: (actor_end..counter_end).into(),
199            })
200        }
201    }
202}