|
| 1 | +// Copyright 2024 The Matrix.org Foundation C.I.C. |
| 2 | +// |
| 3 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +// you may not use this file except in compliance with the License. |
| 5 | +// You may obtain a copy of the License at |
| 6 | +// |
| 7 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +// |
| 9 | +// Unless required by applicable law or agreed to in writing, software |
| 10 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +// See the License for the specific language governing permissions and |
| 13 | +// limitations under the License. |
| 14 | + |
| 15 | +//! Common types for the linked chunk, an internal type used by the event cache. |
| 16 | +//! See `matrix_sdk::event_cache` to learn more. |
| 17 | +
|
| 18 | +/// The unique identifier of a chunk in a `LinkedChunk`. |
| 19 | +/// |
| 20 | +/// It is not the position of the chunk, just its unique identifier. |
| 21 | +/// |
| 22 | +/// Learn more with |
| 23 | +/// `matrix_sdk::event_cache::linked_chunk::ChunkIdentifierGenerator`. |
| 24 | +#[derive(Copy, Clone, Debug, PartialEq)] |
| 25 | +#[repr(transparent)] |
| 26 | +pub struct ChunkIdentifier(pub u64); |
| 27 | + |
| 28 | +#[cfg(test)] |
| 29 | +impl PartialEq<u64> for ChunkIdentifier { |
| 30 | + fn eq(&self, other: &u64) -> bool { |
| 31 | + self.0 == *other |
| 32 | + } |
| 33 | +} |
| 34 | + |
| 35 | +/// The position of something inside a chunk. |
| 36 | +/// |
| 37 | +/// It's a pair of a chunk identifier and an item index. |
| 38 | +#[derive(Copy, Clone, Debug, PartialEq)] |
| 39 | +pub struct Position(pub ChunkIdentifier, pub usize); |
| 40 | + |
| 41 | +impl Position { |
| 42 | + /// Get the chunk identifier of the item. |
| 43 | + pub fn chunk_identifier(&self) -> ChunkIdentifier { |
| 44 | + self.0 |
| 45 | + } |
| 46 | + |
| 47 | + /// Get the index inside the chunk. |
| 48 | + pub fn index(&self) -> usize { |
| 49 | + self.1 |
| 50 | + } |
| 51 | + |
| 52 | + /// Decrement the index part (see [`Self::index`]), i.e. subtract 1. |
| 53 | + /// |
| 54 | + /// # Panic |
| 55 | + /// |
| 56 | + /// This method will panic if it will underflow, i.e. if the index is 0. |
| 57 | + pub fn decrement_index(&mut self) { |
| 58 | + self.1 = self.1.checked_sub(1).expect("Cannot decrement the index because it's already 0"); |
| 59 | + } |
| 60 | +} |
| 61 | + |
| 62 | +/// Represent the updates that have happened inside a `LinkedChunk`. |
| 63 | +/// |
| 64 | +/// To retrieve the updates, use `LinkedChunk::updates`. |
| 65 | +/// |
| 66 | +/// These updates are useful to store a `LinkedChunk` in another form of |
| 67 | +/// storage, like a database or something similar. |
| 68 | +#[derive(Debug, Clone, PartialEq)] |
| 69 | +pub enum Update<Item, Gap> { |
| 70 | + /// A new chunk of kind Items has been created. |
| 71 | + NewItemsChunk { |
| 72 | + /// The identifier of the previous chunk of this new chunk. |
| 73 | + previous: Option<ChunkIdentifier>, |
| 74 | + |
| 75 | + /// The identifier of the new chunk. |
| 76 | + new: ChunkIdentifier, |
| 77 | + |
| 78 | + /// The identifier of the next chunk of this new chunk. |
| 79 | + next: Option<ChunkIdentifier>, |
| 80 | + }, |
| 81 | + |
| 82 | + /// A new chunk of kind Gap has been created. |
| 83 | + NewGapChunk { |
| 84 | + /// The identifier of the previous chunk of this new chunk. |
| 85 | + previous: Option<ChunkIdentifier>, |
| 86 | + |
| 87 | + /// The identifier of the new chunk. |
| 88 | + new: ChunkIdentifier, |
| 89 | + |
| 90 | + /// The identifier of the next chunk of this new chunk. |
| 91 | + next: Option<ChunkIdentifier>, |
| 92 | + |
| 93 | + /// The content of the chunk. |
| 94 | + gap: Gap, |
| 95 | + }, |
| 96 | + |
| 97 | + /// A chunk has been removed. |
| 98 | + RemoveChunk(ChunkIdentifier), |
| 99 | + |
| 100 | + /// Items are pushed inside a chunk of kind Items. |
| 101 | + PushItems { |
| 102 | + /// The [`Position`] of the items. |
| 103 | + /// |
| 104 | + /// This value is given to prevent the need for position computations by |
| 105 | + /// the update readers. Items are pushed, so the positions should be |
| 106 | + /// incrementally computed from the previous items, which requires the |
| 107 | + /// reading of the last previous item. With `at`, the update readers no |
| 108 | + /// longer need to do so. |
| 109 | + at: Position, |
| 110 | + |
| 111 | + /// The items. |
| 112 | + items: Vec<Item>, |
| 113 | + }, |
| 114 | + |
| 115 | + /// An item has been removed inside a chunk of kind Items. |
| 116 | + RemoveItem { |
| 117 | + /// The [`Position`] of the item. |
| 118 | + at: Position, |
| 119 | + }, |
| 120 | + |
| 121 | + /// The last items of a chunk have been detached, i.e. the chunk has been |
| 122 | + /// truncated. |
| 123 | + DetachLastItems { |
| 124 | + /// The split position. Before this position (`..position`), items are |
| 125 | + /// kept, from this position (`position..`), items are |
| 126 | + /// detached. |
| 127 | + at: Position, |
| 128 | + }, |
| 129 | + |
| 130 | + /// Detached items (see [`Self::DetachLastItems`]) starts being reattached. |
| 131 | + StartReattachItems, |
| 132 | + |
| 133 | + /// Reattaching items (see [`Self::StartReattachItems`]) is finished. |
| 134 | + EndReattachItems, |
| 135 | +} |
0 commit comments