1use crate::{tag_index::map_to_index_set, tag_index::TagIndex, tag_index::TagSet};
2use banyan::query::Query;
3use banyan::{index::*, TreeTypes};
4use libipld::{
5 cbor::DagCborCodec,
6 codec::{Decode, Encode},
7 Cid, DagCbor,
8};
9use multihash::{Code, MultihashDigest};
10use serde::{Deserialize, Serialize};
11use std::{
12 convert::{TryFrom, TryInto},
13 fmt,
14 io::{Read, Seek, Write},
15 iter::FromIterator,
16 str::FromStr,
17};
18use vec_collections::VecSet;
19
20#[derive(Debug, Clone)]
21pub struct TT {}
22
23#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
24pub struct Sha256Digest([u8; 32]);
25
26impl Decode<DagCborCodec> for Sha256Digest {
27 fn decode<R: Read + Seek>(c: DagCborCodec, r: &mut R) -> anyhow::Result<Self> {
28 Self::try_from(Cid::decode(c, r)?)
29 }
30}
31impl Encode<DagCborCodec> for Sha256Digest {
32 fn encode<W: Write>(&self, c: DagCborCodec, w: &mut W) -> anyhow::Result<()> {
33 Cid::encode(&Cid::from(*self), c, w)
34 }
35}
36
37impl Sha256Digest {
38 pub fn new(data: &[u8]) -> Self {
39 let mh = multihash::Code::Sha2_256.digest(data);
40 Sha256Digest(mh.digest().try_into().unwrap())
41 }
42
43 pub fn digest(data: &[u8]) -> Self {
44 let mh = Code::Sha2_256.digest(data);
45 Sha256Digest(mh.digest().try_into().unwrap())
46 }
47}
48
49impl From<Sha256Digest> for Cid {
50 fn from(value: Sha256Digest) -> Self {
51 let mh = multihash::Multihash::wrap(0x12, &value.0).unwrap();
53 Cid::new_v1(0x71, mh)
54 }
55}
56
57impl TryFrom<Cid> for Sha256Digest {
58 type Error = anyhow::Error;
59
60 fn try_from(value: Cid) -> Result<Self, Self::Error> {
61 anyhow::ensure!(value.codec() == 0x71, "Unexpected codec");
62 anyhow::ensure!(value.hash().code() == 0x12, "Unexpected hash algorithm");
63 let digest: [u8; 32] = value.hash().digest().try_into()?;
64 Ok(Self(digest))
65 }
66}
67
68impl FromStr for Sha256Digest {
69 type Err = anyhow::Error;
70 fn from_str(s: &str) -> Result<Self, Self::Err> {
71 let cid = Cid::from_str(s)?;
72 cid.try_into()
73 }
74}
75
76impl fmt::Display for Sha256Digest {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 write!(f, "{}", Cid::from(*self))
79 }
80}
81
82impl fmt::Debug for Sha256Digest {
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 write!(f, "{}", Cid::from(*self))
85 }
86}
87
88impl TreeTypes for TT {
89 type Key = Key;
90 type KeySeq = KeySeq;
91 type Summary = Key;
92 type SummarySeq = KeySeq;
93 type Link = Sha256Digest;
94}
95
96#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
97pub struct Key {
98 time: TimeData,
99 tags: TagSet,
100}
101
102#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
103pub struct TimeData {
104 min_lamport: u64,
105 min_time: u64,
106 max_time: u64,
107}
108
109impl TimeData {
110 fn intersects(&self, that: &Self) -> bool {
111 if self.max_time < that.min_time {
112 return false;
113 }
114 if self.min_time > that.max_time {
115 return false;
116 }
117 true
118 }
119
120 fn contains(&self, that: &Self) -> bool {
121 if that.min_time < self.min_time {
122 return false;
123 }
124 if that.max_time > self.max_time {
125 return false;
126 }
127 true
128 }
129
130 fn combine(&mut self, b: &Self) {
131 self.min_lamport = self.min_lamport.min(b.min_lamport);
132 self.min_time = self.min_time.min(b.min_time);
133 self.max_time = self.max_time.max(b.max_time);
134 }
135}
136
137#[allow(dead_code)]
138impl Key {
139 pub fn single(lamport: u64, time: u64, tags: TagSet) -> Self {
140 Self {
141 time: TimeData {
142 min_lamport: lamport,
143 min_time: time,
144 max_time: time,
145 },
146 tags,
147 }
148 }
149
150 pub fn filter_tags(tags: TagSet) -> Self {
151 Self {
152 time: TimeData {
153 min_lamport: u64::MIN,
154 min_time: u64::MIN,
155 max_time: u64::MAX,
156 },
157 tags,
158 }
159 }
160
161 pub fn range(min_time: u64, max_time: u64, tags: TagSet) -> Self {
162 Self {
163 time: TimeData {
164 min_lamport: 0,
165 min_time,
166 max_time,
167 },
168 tags,
169 }
170 }
171
172 fn intersects(&self, that: &Key) -> bool {
173 self.time.intersects(&that.time) && !self.tags.is_disjoint(&that.tags)
174 }
175
176 fn contains(&self, that: &Key) -> bool {
177 self.time.contains(&that.time) && self.tags.is_superset(&that.tags)
178 }
179}
180
181#[allow(dead_code)]
182impl Key {
183 fn combine(&mut self, b: &Self) {
184 self.time.combine(&b.time);
185 self.tags.extend(b.tags.iter().cloned());
186 }
187}
188
189#[derive(Debug)]
190pub struct DnfQuery(pub Vec<Key>);
191
192#[allow(dead_code)]
193impl DnfQuery {
194 fn intersects(&self, v: &Key) -> bool {
195 self.0.iter().any(|x| x.intersects(v))
196 }
197 fn contains(&self, v: &Key) -> bool {
198 self.0.iter().any(|x| x.contains(v))
199 }
200 fn map_into<'a>(&self, keyseq: &'a KeySeq) -> TranslatedDnfQuery<'a> {
201 TranslatedDnfQuery {
202 query: self
203 .0
204 .iter()
205 .map(|key| {
206 map_to_index_set(&keyseq.tags.tags, &key.tags).map(|index_set| TranslatedKey {
207 index_set,
208 time: key.time,
209 })
210 })
211 .collect::<Option<Vec<_>>>()
212 .unwrap_or_default(),
213 seq: keyseq,
214 }
215 }
216}
217
218type IndexSet = VecSet<[u32; 4]>;
219
220struct TranslatedKey {
221 index_set: IndexSet,
222 time: TimeData,
223}
224
225struct TranslatedDnfQuery<'a> {
226 query: Vec<TranslatedKey>,
227 seq: &'a KeySeq,
228}
229
230impl<'a> TranslatedDnfQuery<'a> {
231 fn intersects(&self, i: usize) -> bool {
232 self.query.iter().any(|q| {
233 q.time.intersects(&self.seq.time(i).unwrap())
234 && !q.index_set.is_disjoint(&self.seq.tags.elements[i])
235 })
236 }
237
238 fn contains(&self, i: usize) -> bool {
239 self.query.iter().any(|q| {
240 q.time.contains(&self.seq.time(i).unwrap())
241 && q.index_set.is_superset(&self.seq.tags.elements[i])
242 })
243 }
244
245 fn intersecting(&self, matching: &mut [bool]) {
246 for i in 0..self.seq.len().min(matching.len()) {
247 if matching[i] {
248 matching[i] = self.intersects(i);
249 }
250 }
251 }
252
253 fn containing(&self, matching: &mut [bool]) {
254 for i in 0..self.seq.len().min(matching.len()) {
255 if matching[i] {
256 matching[i] = self.contains(i);
257 }
258 }
259 }
260}
261
262impl Query<TT> for DnfQuery {
263 fn intersecting(&self, _: u64, x: &BranchIndex<TT>, matching: &mut [bool]) {
264 self.map_into(&x.summaries).intersecting(matching);
265 }
271 fn containing(&self, _: u64, x: &LeafIndex<TT>, matching: &mut [bool]) {
272 self.map_into(&x.keys).containing(matching);
273 }
279}
280
281#[derive(Clone, Debug, Serialize, Deserialize, DagCbor)]
282pub struct KeySeq {
283 min_lamport: Vec<u64>,
284 min_time: Vec<u64>,
285 max_time: Vec<u64>,
286 tags: TagIndex,
287}
288
289impl KeySeq {
290 fn time(&self, i: usize) -> Option<TimeData> {
291 if i < self.min_lamport.len() {
292 Some(TimeData {
293 min_time: self.min_time[i],
294 max_time: self.max_time[i],
295 min_lamport: self.min_lamport[i],
296 })
297 } else {
298 None
299 }
300 }
301}
302
303impl CompactSeq for KeySeq {
304 type Item = Key;
305
306 fn get(&self, index: usize) -> Option<Key> {
307 if let (Some(min_lamport), Some(min_time), Some(max_time), Some(tags)) = (
308 self.min_lamport.get(index),
309 self.min_time.get(index),
310 self.max_time.get(index),
311 self.tags.get(index),
312 ) {
313 Some(Key {
314 time: TimeData {
315 min_lamport: *min_lamport,
316 min_time: *min_time,
317 max_time: *max_time,
318 },
319 tags,
320 })
321 } else {
322 None
323 }
324 }
325
326 fn len(&self) -> usize {
327 self.tags.elements.len()
328 }
329
330 fn estimated_size(&self) -> usize {
331 self.len() * 128
332 }
333}
334
335impl Summarizable<Key> for KeySeq {
336 fn summarize(&self) -> Key {
337 let max_time = *self.max_time.iter().max().unwrap();
338 let min_time = *self.min_time.iter().min().unwrap();
339 let min_lamport = *self.min_lamport.iter().min().unwrap();
340 let tags = self.tags.tags.clone();
341 Key {
342 time: TimeData {
343 min_lamport,
344 min_time,
345 max_time,
346 },
347 tags,
348 }
349 }
355}
356
357impl FromIterator<Key> for KeySeq {
358 fn from_iter<T: IntoIterator<Item = Key>>(iter: T) -> Self {
359 let mut min_lamport = Vec::new();
360 let mut min_time = Vec::new();
361 let mut max_time = Vec::new();
362 let mut tag_index = Vec::new();
363 for value in iter.into_iter() {
364 min_lamport.push(value.time.min_lamport);
365 min_time.push(value.time.min_time);
366 max_time.push(value.time.max_time);
367 tag_index.push(value.tags);
368 }
369 let tag_index = TagIndex::from_elements(&tag_index);
370 Self {
371 min_lamport,
372 min_time,
373 max_time,
374 tags: tag_index,
375 }
376 }
377}