1
use std::{
2
    array::TryFromSliceError,
3
    collections::HashMap,
4
    fmt::{Debug, Display},
5
    ops::RangeBounds,
6
};
7

            
8
use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
9

            
10
use super::{
11
    btree::BTreeEntry,
12
    by_id::{ByIdStats, VersionedByIdIndex},
13
    by_sequence::{BySequenceIndex, BySequenceStats},
14
    modify::Modification,
15
    serialization::BinarySerialization,
16
    ChangeResult, PagedWriter, ScanEvaluation, PAGE_SIZE,
17
};
18
use crate::{
19
    chunk_cache::CacheEntry,
20
    error::{Error, InternalError},
21
    io::File,
22
    roots::AbortError,
23
    transaction::TransactionId,
24
    tree::{
25
        btree::{Indexer, KeyOperation, ModificationContext, NodeInclusion, ScanArgs},
26
        by_id::ByIdIndexer,
27
        by_sequence::{BySequenceReducer, SequenceId},
28
        dynamic_order,
29
        key_entry::KeyEntry,
30
        modify::Operation,
31
        BTreeNode, Interior, ModificationResult, PageHeader, PersistenceMode, Reducer, Root,
32
    },
33
    vault::AnyVault,
34
    ArcBytes, ChunkCache, ErrorKind,
35
};
36

            
37
/// An versioned tree with no additional indexed data.
38
pub type Versioned = VersionedTreeRoot<()>;
39

            
40
/// A versioned B-Tree root. This tree root internally uses two btrees, one to
41
/// keep track of all writes using a unique "sequence" ID, and one that keeps
42
/// track of all key-value pairs.
43
36217
#[derive(Clone, Debug)]
44
pub struct VersionedTreeRoot<EmbeddedIndex>
45
where
46
    EmbeddedIndex: super::EmbeddedIndex<ArcBytes<'static>>,
47
{
48
    /// The transaction ID of the tree root. If this transaction ID isn't
49
    /// present in the transaction log, this root should not be trusted.
50
    pub transaction_id: TransactionId,
51
    /// The last sequence ID inside of this root.
52
    pub sequence: SequenceId,
53
    /// The by-sequence B-Tree.
54
    pub by_sequence_root: BTreeEntry<BySequenceIndex<EmbeddedIndex>, BySequenceStats>,
55
    /// The by-id B-Tree.
56
    pub by_id_root: BTreeEntry<
57
        VersionedByIdIndex<EmbeddedIndex, ArcBytes<'static>>,
58
        ByIdStats<EmbeddedIndex::Reduced>,
59
    >,
60

            
61
    reducer: ByIdIndexer<EmbeddedIndex::Indexer>,
62
}
63
impl<EmbeddedIndex> Default for VersionedTreeRoot<EmbeddedIndex>
64
where
65
    EmbeddedIndex: super::EmbeddedIndex<ArcBytes<'static>> + Clone + Debug + 'static,
66
    EmbeddedIndex::Indexer: Default,
67
{
68
6071
    fn default() -> Self {
69
6071
        Self {
70
6071
            transaction_id: TransactionId(0),
71
6071
            sequence: SequenceId(0),
72
6071
            by_sequence_root: BTreeEntry::default(),
73
6071
            by_id_root: BTreeEntry::default(),
74
6071
            reducer: ByIdIndexer(<EmbeddedIndex::Indexer as Default>::default()),
75
6071
        }
76
6071
    }
77
}
78

            
79
#[derive(Debug)]
80
pub enum Children<Index, ReducedIndex> {
81
    Leaves(Vec<KeyEntry<Index>>),
82
    Interiors(Vec<Interior<Index, ReducedIndex>>),
83
}
84

            
85
impl<EmbeddedIndex> VersionedTreeRoot<EmbeddedIndex>
86
where
87
    EmbeddedIndex: super::EmbeddedIndex<ArcBytes<'static>> + Clone + Debug + 'static,
88
    ByIdIndexer<EmbeddedIndex::Indexer>: Reducer<
89
        VersionedByIdIndex<EmbeddedIndex, ArcBytes<'static>>,
90
        ByIdStats<EmbeddedIndex::Reduced>,
91
    >,
92
{
93
    fn modify_sequence_root(
94
        &mut self,
95
        mut modification: Modification<
96
            '_,
97
            BySequenceIndex<EmbeddedIndex>,
98
            BySequenceIndex<EmbeddedIndex>,
99
        >,
100
        writer: &mut PagedWriter<'_>,
101
        max_order: Option<usize>,
102
    ) -> Result<(), Error> {
103
        // Reverse so that pop is efficient.
104
20453
        modification.prepare()?;
105

            
106
20453
        let total_sequence_records = self
107
20453
            .by_sequence_root
108
20453
            .stats(&BySequenceReducer)
109
20453
            .total_sequences
110
20453
            + modification.keys.len() as u64;
111
20453
        let by_sequence_order = dynamic_order(total_sequence_records, max_order);
112
20453

            
113
20453
        let by_sequence_minimum_children = by_sequence_order / 2 - 1;
114
20453
        let by_sequence_minimum_children = by_sequence_minimum_children
115
20453
            .min(usize::try_from(total_sequence_records).unwrap_or(usize::MAX));
116

            
117
40903
        while !modification.keys.is_empty() {
118
20450
            match self.by_sequence_root.modify(
119
20450
                &mut modification,
120
20450
                &mut ModificationContext::new(
121
20450
                    by_sequence_order,
122
20450
                    by_sequence_minimum_children,
123
20450
                    |_key: &ArcBytes<'_>,
124
                     value: Option<&BySequenceIndex<EmbeddedIndex>>,
125
                     _existing_index: Option<&BySequenceIndex<EmbeddedIndex>>,
126
232798
                     _writer: &mut PagedWriter<'_>| {
127
232798
                        Ok(KeyOperation::Set(value.unwrap().clone()))
128
232798
                    },
129
20450
                    |_index: &BySequenceIndex<EmbeddedIndex>, _writer: &mut PagedWriter<'_>| {
130
                        Ok(None)
131
20450
                    },
132
20450
                    BySequenceReducer,
133
20450
                ),
134
20450
                None,
135
20450
                writer,
136
20450
            )? {
137
                ChangeResult::Absorb
138
                | ChangeResult::Remove
139
                | ChangeResult::Unchanged
140
18429
                | ChangeResult::Changed => {}
141
2021
                ChangeResult::Split => {
142
2021
                    self.by_sequence_root.split_root(&BySequenceReducer);
143
2021
                }
144
            }
145
        }
146
20453
        Ok(())
147
20453
    }
148

            
149
    fn modify_id_root(
150
        &mut self,
151
        mut modification: Modification<
152
            '_,
153
            ArcBytes<'static>,
154
            VersionedByIdIndex<EmbeddedIndex, ArcBytes<'static>>,
155
        >,
156
        changes: &mut EntryChanges<EmbeddedIndex>,
157
        writer: &mut PagedWriter<'_>,
158
        max_order: Option<usize>,
159
    ) -> Result<Vec<ModificationResult<VersionedByIdIndex<EmbeddedIndex, ArcBytes<'static>>>>, Error>
160
    {
161
20453
        modification.prepare()?;
162

            
163
20453
        let total_id_records =
164
20453
            self.by_id_root.stats(self.reducer()).total_keys() + modification.keys.len() as u64;
165
20453
        let by_id_order = dynamic_order(total_id_records, max_order);
166
20453

            
167
20453
        let by_id_minimum_children = by_id_order / 2 - 1;
168
20453
        let by_id_minimum_children =
169
20453
            by_id_minimum_children.min(usize::try_from(total_id_records).unwrap_or(usize::MAX));
170
20453

            
171
20453
        let mut results = Vec::with_capacity(modification.keys.len());
172

            
173
40911
        while !modification.keys.is_empty() {
174
20458
            let reducer = self.reducer.clone();
175
20458
            match self.by_id_root.modify(
176
20458
                &mut modification,
177
20458
                &mut ModificationContext::new(
178
20458
                    by_id_order,
179
20458
                    by_id_minimum_children,
180
20458
                    |key: &ArcBytes<'_>,
181
                     value: Option<&ArcBytes<'static>>,
182
                     existing_index: Option<
183
                        &VersionedByIdIndex<EmbeddedIndex, ArcBytes<'static>>,
184
                    >,
185
232798
                     writer: &mut PagedWriter<'_>| {
186
232798
                        let (position, value_size) = if let Some(value) = value {
187
151335
                            let new_position = writer.write_chunk_cached(value.clone())?;
188
                            // write_chunk errors if it can't fit within a u32
189
                            #[allow(clippy::cast_possible_truncation)]
190
151335
                            let value_length = value.len() as u32;
191
151335
                            (new_position, value_length)
192
                        } else {
193
81463
                            (0, 0)
194
                        };
195
232798
                        let embedded = reducer.0.index(key, value);
196
232798
                        changes.current_sequence = changes
197
232798
                            .current_sequence
198
232798
                            .next_sequence()
199
232798
                            .expect("sequence rollover prevented");
200
232798
                        let key = key.to_owned();
201
232798
                        changes.changes.push(EntryChange {
202
232798
                            key_sequence: KeySequence {
203
232798
                                key: key.clone(),
204
232798
                                sequence: changes.current_sequence,
205
232798
                                last_sequence: existing_index.map(|idx| idx.sequence_id),
206
232798
                                embedded: Some(embedded.clone()),
207
232798
                            },
208
232798
                            value_position: position,
209
232798
                            value_size,
210
232798
                        });
211
232798
                        let new_index = VersionedByIdIndex::new(
212
232798
                            changes.current_sequence,
213
232798
                            value_size,
214
232798
                            position,
215
232798
                            embedded,
216
232798
                        );
217
232798
                        results.push(ModificationResult {
218
232798
                            key,
219
232798
                            index: Some(new_index.clone()),
220
232798
                        });
221
232798
                        Ok(KeyOperation::Set(new_index))
222
232798
                    },
223
80476
                    |index, writer| {
224
80476
                        if index.position > 0 {
225
80475
                            match writer.read_chunk(index.position) {
226
80475
                                Ok(CacheEntry::ArcBytes(buffer)) => Ok(Some(buffer)),
227
                                Ok(CacheEntry::Decoded(_)) => unreachable!(),
228
                                Err(err) => Err(err),
229
                            }
230
                        } else {
231
1
                            Ok(None)
232
                        }
233
80476
                    },
234
20458
                    self.reducer().clone(),
235
20458
                ),
236
20458
                None,
237
20458
                writer,
238
20458
            )? {
239
20423
                ChangeResult::Absorb | ChangeResult::Changed | ChangeResult::Unchanged => {}
240
                ChangeResult::Remove => {
241
                    self.by_id_root.node = BTreeNode::Leaf(vec![]);
242
                    self.by_id_root.dirty = true;
243
                }
244
35
                ChangeResult::Split => {
245
35
                    self.by_id_root.split_root(&self.reducer().clone());
246
35
                }
247
            }
248
        }
249

            
250
20453
        self.sequence = changes.current_sequence;
251
20453

            
252
20453
        Ok(results)
253
20453
    }
254
}
255

            
256
impl<EmbeddedIndex> Root for VersionedTreeRoot<EmbeddedIndex>
257
where
258
    EmbeddedIndex: super::EmbeddedIndex<ArcBytes<'static>> + Clone + Debug + 'static,
259
{
260
    const HEADER: PageHeader = PageHeader::VersionedHeader;
261
    type Value = ArcBytes<'static>;
262
    type Index = VersionedByIdIndex<EmbeddedIndex, Self::Value>;
263
    type ReducedIndex = ByIdStats<EmbeddedIndex::Reduced>;
264
    type Reducer = ByIdIndexer<EmbeddedIndex::Indexer>;
265

            
266
15
    fn default_with(reducer: Self::Reducer) -> Self {
267
15
        Self {
268
15
            transaction_id: TransactionId(0),
269
15
            sequence: SequenceId(0),
270
15
            by_sequence_root: BTreeEntry::default(),
271
15
            by_id_root: BTreeEntry::default(),
272
15
            reducer,
273
15
        }
274
15
    }
275

            
276
52387
    fn reducer(&self) -> &Self::Reducer {
277
52387
        &self.reducer
278
52387
    }
279

            
280
1796
    fn count(&self) -> u64 {
281
1796
        self.by_id_root.stats(self.reducer()).alive_keys
282
1796
    }
283

            
284
12300
    fn dirty(&self) -> bool {
285
12300
        self.by_id_root.dirty || self.by_sequence_root.dirty
286
12300
    }
287

            
288
30360
    fn initialized(&self) -> bool {
289
30360
        self.sequence.valid()
290
30360
    }
291

            
292
35
    fn initialize_default(&mut self) {
293
35
        self.sequence = SequenceId(1);
294
35
    }
295

            
296
22247
    fn serialize(
297
22247
        &mut self,
298
22247
        paged_writer: &mut PagedWriter<'_>,
299
22247
        output: &mut Vec<u8>,
300
22247
    ) -> Result<(), Error> {
301
22247
        output.reserve(PAGE_SIZE);
302
22247
        output.write_u64::<BigEndian>(self.transaction_id.0)?;
303
22247
        output.write_u64::<BigEndian>(self.sequence.0)?;
304
        // Reserve space for by_sequence and by_id sizes (2xu32).
305
22247
        output.write_u64::<BigEndian>(0)?;
306

            
307
22247
        let by_sequence_size = self.by_sequence_root.serialize_to(output, paged_writer)?;
308

            
309
22247
        let by_id_size = self.by_id_root.serialize_to(output, paged_writer)?;
310

            
311
22247
        let by_sequence_size = u32::try_from(by_sequence_size)
312
22247
            .ok()
313
22247
            .ok_or(ErrorKind::Internal(InternalError::HeaderTooLarge))?;
314
22247
        BigEndian::write_u32(&mut output[16..20], by_sequence_size);
315
22247
        let by_id_size = u32::try_from(by_id_size)
316
22247
            .ok()
317
22247
            .ok_or(ErrorKind::Internal(InternalError::HeaderTooLarge))?;
318
22247
        BigEndian::write_u32(&mut output[20..24], by_id_size);
319
22247

            
320
22247
        Ok(())
321
22247
    }
322

            
323
6053
    fn deserialize(mut bytes: ArcBytes<'_>, reducer: Self::Reducer) -> Result<Self, Error> {
324
6053
        let transaction_id = TransactionId(bytes.read_u64::<BigEndian>()?);
325
6053
        let sequence = SequenceId(bytes.read_u64::<BigEndian>()?);
326
6053
        let by_sequence_size = bytes.read_u32::<BigEndian>()? as usize;
327
6053
        let by_id_size = bytes.read_u32::<BigEndian>()? as usize;
328
6053
        if by_sequence_size + by_id_size != bytes.len() {
329
2
            return Err(Error::data_integrity(format!(
330
2
                "Header reported index sizes {} and {}, but data has {} remaining",
331
2
                by_sequence_size,
332
2
                by_id_size,
333
2
                bytes.len()
334
2
            )));
335
6051
        }
336

            
337
6051
        let mut by_sequence_bytes = bytes.read_bytes(by_sequence_size)?.to_owned();
338
6051
        let mut by_id_bytes = bytes.read_bytes(by_id_size)?.to_owned();
339

            
340
6051
        let by_sequence_root = BTreeEntry::deserialize_from(&mut by_sequence_bytes, None)?;
341
6051
        let by_id_root = BTreeEntry::deserialize_from(&mut by_id_bytes, None)?;
342

            
343
6051
        Ok(Self {
344
6051
            transaction_id,
345
6051
            sequence,
346
6051
            by_sequence_root,
347
6051
            by_id_root,
348
6051
            reducer,
349
6051
        })
350
6053
    }
351

            
352
6
    fn transaction_id(&self) -> TransactionId {
353
6
        self.transaction_id
354
6
    }
355

            
356
20453
    fn modify(
357
20453
        &mut self,
358
20453
        modification: Modification<'_, ArcBytes<'static>, Self::Index>,
359
20453
        writer: &mut PagedWriter<'_>,
360
20453
        max_order: Option<usize>,
361
20453
    ) -> Result<Vec<ModificationResult<Self::Index>>, Error> {
362
20453
        let persistence_mode = modification.persistence_mode;
363
20453

            
364
20453
        // Insert into both trees
365
20453
        let mut changes = EntryChanges {
366
20453
            current_sequence: self.sequence,
367
20453
            changes: Vec::with_capacity(modification.keys.len()),
368
20453
        };
369
20453
        let results = self.modify_id_root(modification, &mut changes, writer, max_order)?;
370

            
371
        // Convert the changes into a modification request for the id root.
372
20453
        let mut values = Vec::with_capacity(changes.changes.len());
373
20453
        let keys = changes
374
20453
            .changes
375
20453
            .into_iter()
376
232798
            .map(|change| {
377
232798
                values.push(BySequenceIndex {
378
232798
                    key: change.key_sequence.key,
379
232798
                    last_sequence: change.key_sequence.last_sequence,
380
232798
                    value_length: change.value_size,
381
232798
                    position: change.value_position,
382
232798
                    embedded: change.key_sequence.embedded,
383
232798
                });
384
232798
                ArcBytes::from(change.key_sequence.sequence.0.to_be_bytes())
385
232798
            })
386
20453
            .collect();
387
20453
        let sequence_modifications = Modification {
388
20453
            persistence_mode,
389
20453
            keys,
390
20453
            operation: Operation::SetEach(values),
391
20453
        };
392
20453

            
393
20453
        self.modify_sequence_root(sequence_modifications, writer, max_order)?;
394

            
395
        // Only update the transaction id if a new one was specified.
396
20453
        if let Some(transaction_id) = persistence_mode.transaction_id() {
397
12302
            self.transaction_id = transaction_id;
398
12302
        }
399

            
400
20453
        Ok(results)
401
20453
    }
402

            
403
30181
    fn get_multiple<'keys, KeyEvaluator, KeyReader, Keys>(
404
30181
        &self,
405
30181
        keys: &mut Keys,
406
30181
        key_evaluator: &mut KeyEvaluator,
407
30181
        key_reader: &mut KeyReader,
408
30181
        file: &mut dyn File,
409
30181
        vault: Option<&dyn AnyVault>,
410
30181
        cache: Option<&ChunkCache>,
411
30181
    ) -> Result<(), Error>
412
30181
    where
413
30181
        KeyEvaluator: FnMut(&ArcBytes<'static>, &Self::Index) -> ScanEvaluation,
414
30181
        KeyReader: FnMut(ArcBytes<'static>, ArcBytes<'static>, Self::Index) -> Result<(), Error>,
415
30181
        Keys: Iterator<Item = &'keys [u8]>,
416
30181
    {
417
30181
        self.by_id_root
418
30181
            .get_multiple(keys, key_evaluator, key_reader, file, vault, cache)
419
30181
    }
420

            
421
21
    fn scan<
422
21
        'keys,
423
21
        CallerError: Display + Debug,
424
21
        NodeEvaluator,
425
21
        KeyRangeBounds,
426
21
        KeyEvaluator,
427
21
        ScanDataCallback,
428
21
    >(
429
21
        &self,
430
21
        range: &'keys KeyRangeBounds,
431
21
        mut args: ScanArgs<
432
21
            Self::Value,
433
21
            Self::Index,
434
21
            Self::ReducedIndex,
435
21
            CallerError,
436
21
            NodeEvaluator,
437
21
            KeyEvaluator,
438
21
            ScanDataCallback,
439
21
        >,
440
21
        file: &mut dyn File,
441
21
        vault: Option<&dyn AnyVault>,
442
21
        cache: Option<&ChunkCache>,
443
21
    ) -> Result<bool, AbortError<CallerError>>
444
21
    where
445
21
        NodeEvaluator: FnMut(&ArcBytes<'static>, &Self::ReducedIndex, usize) -> ScanEvaluation,
446
21
        KeyEvaluator: FnMut(&ArcBytes<'static>, &Self::Index) -> ScanEvaluation,
447
21
        KeyRangeBounds: RangeBounds<&'keys [u8]> + Debug + ?Sized,
448
21
        ScanDataCallback: FnMut(
449
21
            ArcBytes<'static>,
450
21
            &Self::Index,
451
21
            ArcBytes<'static>,
452
21
        ) -> Result<(), AbortError<CallerError>>,
453
21
    {
454
21
        self.by_id_root
455
21
            .scan(range, &mut args, file, vault, cache, 0)
456
21
    }
457

            
458
3592
    fn copy_data_to(
459
3592
        &mut self,
460
3592
        include_nodes: bool,
461
3592
        file: &mut dyn File,
462
3592
        copied_chunks: &mut HashMap<u64, u64>,
463
3592
        writer: &mut PagedWriter<'_>,
464
3592
        vault: Option<&dyn AnyVault>,
465
3592
    ) -> Result<(), Error> {
466
3592
        // Copy all of the data using the ID root.
467
3592
        let mut sequence_indexes = Vec::with_capacity(
468
3592
            usize::try_from(self.by_id_root.stats(self.reducer()).alive_keys).unwrap_or(usize::MAX),
469
3592
        );
470
3592
        let mut scratch = Vec::new();
471
3592
        self.by_id_root.copy_data_to(
472
3592
            if include_nodes {
473
1796
                NodeInclusion::IncludeNext
474
            } else {
475
1796
                NodeInclusion::Exclude
476
            },
477
3592
            file,
478
3592
            copied_chunks,
479
3592
            writer,
480
3592
            vault,
481
3592
            &mut scratch,
482
3592
            &mut |key,
483
                  index: &mut VersionedByIdIndex<EmbeddedIndex, ArcBytes<'static>>,
484
                  from_file,
485
                  copied_chunks,
486
                  to_file,
487
1892962
                  vault| {
488
1892962
                let new_position =
489
1892962
                    to_file.copy_chunk_from(index.position, from_file, copied_chunks, vault)?;
490

            
491
1892962
                sequence_indexes.push((
492
1892962
                    key.clone(),
493
1892962
                    BySequenceIndex {
494
1892962
                        key: key.clone(),
495
1892962
                        last_sequence: None,
496
1892962
                        value_length: index.value_length,
497
1892962
                        position: new_position,
498
1892962
                        embedded: Some(index.embedded.clone()),
499
1892962
                    },
500
1892962
                ));
501
1892962

            
502
1892962
                index.position = new_position;
503
1892962
                Ok(true)
504
1892962
            },
505
        )?;
506

            
507
        // Replace our by_sequence index with a new truncated one.
508
3592
        self.by_sequence_root = BTreeEntry::default();
509
3592

            
510
1889370
        sequence_indexes.sort_by(|a, b| a.0.cmp(&b.0));
511
3592
        let by_sequence_order = dynamic_order(sequence_indexes.len() as u64, None);
512
3592
        let mut keys = Vec::with_capacity(sequence_indexes.len());
513
3592
        let mut indexes = Vec::with_capacity(sequence_indexes.len());
514
1896554
        for (id, index) in sequence_indexes {
515
1892962
            keys.push(id);
516
1892962
            indexes.push(index);
517
1892962
        }
518

            
519
3592
        let mut modification = Modification {
520
3592
            persistence_mode: PersistenceMode::Transactional(self.transaction_id),
521
3592
            keys,
522
3592
            operation: Operation::SetEach(indexes),
523
3592
        };
524
3592

            
525
3592
        let minimum_children = by_sequence_order / 2 - 1;
526
3592
        let minimum_children = minimum_children.min(modification.keys.len());
527
3592

            
528
3592
        // This modification copies the `sequence_indexes` into the sequence root.
529
3592
        self.by_sequence_root.modify(
530
3592
            &mut modification,
531
3592
            &mut ModificationContext::new(
532
3592
                by_sequence_order,
533
3592
                minimum_children,
534
3592
                |_key: &ArcBytes<'_>,
535
                               value: Option<&BySequenceIndex<EmbeddedIndex>>,
536
                               _existing_index: Option<&BySequenceIndex<EmbeddedIndex>>,
537
29516
                               _writer: &mut PagedWriter<'_>| {
538
29516
                    Ok(KeyOperation::Set(value.unwrap().clone()))
539
29516
                },
540
3592
                |_index: &BySequenceIndex<EmbeddedIndex>, _writer: &mut PagedWriter<'_>| unreachable!(),
541
3592
                BySequenceReducer,
542
3592
            ),
543
3592
            None,
544
3592
            writer,
545
3592
        )?;
546

            
547
3592
        Ok(())
548
3592
    }
549
}
550

            
551
pub struct EntryChanges<Embedded> {
552
    pub current_sequence: SequenceId,
553
    pub changes: Vec<EntryChange<Embedded>>,
554
}
555

            
556
impl<Embedded> Default for EntryChanges<Embedded> {
557
    fn default() -> Self {
558
        Self {
559
            current_sequence: SequenceId::default(),
560
            changes: Vec::default(),
561
        }
562
    }
563
}
564

            
565
pub struct EntryChange<Embedded> {
566
    pub key_sequence: KeySequence<Embedded>,
567
    pub value_position: u64,
568
    pub value_size: u32,
569
}
570

            
571
/// A stored revision of a key.
572
#[derive(Debug)]
573
pub struct KeySequence<Embedded> {
574
    /// The key that this entry was written for.
575
    pub key: ArcBytes<'static>,
576
    /// The unique sequence id.
577
    pub sequence: SequenceId,
578
    /// The previous sequence id for this key, if any.
579
    pub last_sequence: Option<SequenceId>,
580
    /// The embedded index stored for this sequence.
581
    pub embedded: Option<Embedded>,
582
}
583

            
584
impl<'a> TryFrom<&'a [u8]> for SequenceId {
585
    type Error = TryFromSliceError;
586

            
587
    fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
588
        value.try_into().map(u64::from_be_bytes).map(Self)
589
    }
590
}
591

            
592
/// A stored entry in a versioned tree.
593
#[derive(Debug)]
594
pub struct SequenceEntry<Embedded> {
595
    /// The stored index for this sequence id.
596
    pub index: BySequenceIndex<Embedded>,
597
    /// The value stored for this sequence id, if still present.
598
    pub value: Option<ArcBytes<'static>>,
599
}
600

            
601
/// A stored index in a versioned tree.
602
#[derive(Debug)]
603
pub struct SequenceIndex<Embedded> {
604
    /// The unique sequence id.
605
    pub sequence: SequenceId,
606
    /// The stored index for this sequence id.
607
    pub index: BySequenceIndex<Embedded>,
608
}