docs: add comment for last&end

This commit is contained in:
Zixuan Chen 2023-02-08 16:56:06 +08:00
parent 850cd722a4
commit 11b16e85cd
7 changed files with 38 additions and 23 deletions

View file

@ -121,7 +121,7 @@ impl Tracker {
let mut len = 0;
for marker in self
.id_to_cursor
.get_range(id_span.min_id().into(), id_span.end_id().into())
.get_range(id_span.norm_id_start().into(), id_span.norm_id_end().into())
{
for span in marker.get_spans(id_span) {
len += span.len;

View file

@ -245,7 +245,9 @@ impl CursorMap {
let mut deletes: Vec<(ID, RleVecWithLen<[IdSpan; 2]>)> =
Vec::with_capacity(span.atom_len() / 10);
let mut inserted_set = fxhash::FxHashSet::default();
for (id, marker) in self.get_range_with_index(span.min_id().into(), span.end_id().into()) {
for (id, marker) in
self.get_range_with_index(span.norm_id_start().into(), span.norm_id_end().into())
{
let id: ID = id.into();
match marker {
Marker::Insert { .. } => {
@ -265,7 +267,8 @@ impl CursorMap {
Marker::Delete(del) => {
if span.intersect(&id.to_span(del.atom_len())) {
let from = (span.counter.min() - id.counter).max(0);
let to = (span.counter.end() - id.counter).min(del.atom_len() as Counter);
let to =
(span.counter.norm_end() - id.counter).min(del.atom_len() as Counter);
if to - from > 0 {
deletes.push((id.inc(from), del.slice(from as usize, to as usize)));
}
@ -278,7 +281,9 @@ impl CursorMap {
}
pub fn get_first_cursors_at_id_span(&self, span: IdSpan) -> Option<FirstCursorResult> {
for (id, marker) in self.get_range_with_index(span.min_id().into(), span.end_id().into()) {
for (id, marker) in
self.get_range_with_index(span.norm_id_start().into(), span.norm_id_end().into())
{
let start_id: u128 = id.max(span.id_start().into());
let end_id: u128 = span.id_end().into();
let from = (start_id - id) as usize;

View file

@ -125,7 +125,7 @@ impl LogStore {
let mut ans = Vec::with_capacity(id_span.atom_len() / 30);
for change in changes.slice_iter(
id_span.counter.min() as usize,
id_span.counter.end() as usize,
id_span.counter.norm_end() as usize,
) {
let change = change.value.slice(change.start, change.end);
ans.push(change);

View file

@ -94,7 +94,7 @@ impl<'a> Iterator for OpSpanIter<'a> {
let op = RichOp::new_by_slice_on_change(
change,
self.span.counter.min() - change.id.counter,
self.span.counter.end() - change.id.counter,
self.span.counter.norm_end() - change.id.counter,
op,
);
if op.atom_len() == 0 {

View file

@ -88,7 +88,8 @@ impl CounterSpan {
}
#[inline(always)]
pub fn end(&self) -> i32 {
/// This is different from end. start may be greater than end. This is the max of start+1 and end
pub fn norm_end(&self) -> i32 {
if self.start < self.end {
self.end
} else {
@ -195,11 +196,6 @@ impl IdSpan {
self.counter.end < self.counter.start
}
#[inline(always)]
pub fn id_at_begin(&self) -> ID {
ID::new(self.client_id, self.counter.start)
}
#[inline(always)]
pub fn reverse(&mut self) {
self.counter.reverse();
@ -210,14 +206,16 @@ impl IdSpan {
self.counter.normalize_();
}
/// This is different from id_start. id_start may be greater than id_end, but this is the min of id_start and id_end-1
#[inline]
pub fn min_id(&self) -> ID {
pub fn norm_id_start(&self) -> ID {
ID::new(self.client_id, self.counter.min())
}
/// This is different from id_end. id_start may be greater than id_end. This is the max of id_start+1 and id_end
#[inline]
pub fn end_id(&self) -> ID {
ID::new(self.client_id, self.counter.end())
pub fn norm_id_end(&self) -> ID {
ID::new(self.client_id, self.counter.norm_end())
}
pub fn to_id_span_vec(self) -> IdSpanVector {
@ -263,10 +261,12 @@ pub trait HasCounter {
}
pub trait HasCounterSpan: HasCounter + HasLength {
/// end is the exclusive end, last the inclusive end.
fn ctr_end(&self) -> Counter {
self.ctr_start() + self.atom_len() as Counter
}
/// end is the exclusive end, last the inclusive end.
fn ctr_last(&self) -> Counter {
self.ctr_start() + self.atom_len() as Counter - 1
}
@ -312,10 +312,12 @@ pub trait HasIdSpan: HasId + HasLength {
)
}
/// end is the exclusive end, last the inclusive end.
fn id_end(&self) -> ID {
self.id_start().inc(self.content_len() as i32)
}
/// end is the exclusive end, last the inclusive end.
fn id_last(&self) -> ID {
self.id_start().inc(self.content_len() as i32 - 1)
}
@ -337,10 +339,12 @@ pub trait HasLamport {
}
pub trait HasLamportSpan: HasLamport + HasLength {
/// end is the exclusive end, last the inclusive end.
fn lamport_end(&self) -> Lamport {
self.lamport() + self.content_len() as Lamport
}
/// end is the exclusive end, last the inclusive end.
fn lamport_last(&self) -> Lamport {
self.lamport() + self.content_len() as Lamport - 1
}
@ -350,7 +354,7 @@ impl<T: HasLamport + HasLength> HasLamportSpan for T {}
impl HasId for IdSpan {
#[inline]
fn id_start(&self) -> ID {
self.min_id()
self.norm_id_start()
}
}

View file

@ -430,11 +430,11 @@ impl VersionVector {
pub fn extend_to_include(&mut self, span: IdSpan) {
if let Some(counter) = self.get_mut(&span.client_id) {
if *counter < span.counter.end() {
*counter = span.counter.end();
if *counter < span.counter.norm_end() {
*counter = span.counter.norm_end();
}
} else {
self.insert(span.client_id, span.counter.end());
self.insert(span.client_id, span.counter.norm_end());
}
}
@ -667,12 +667,12 @@ impl PatchedVersionVector {
};
if let Some(counter) = self.patch.get_mut(&span.client_id) {
if *counter < span.counter.end() {
*counter = span.counter.end();
if *counter < span.counter.norm_end() {
*counter = span.counter.norm_end();
self.omit_if_needless(span.client_id);
}
} else {
let target = span.counter.end();
let target = span.counter.norm_end();
if self.base.get(&span.client_id) == Some(&target) {
continue;
}

View file

@ -17,7 +17,7 @@
| Lamport | [Lamport timestamp](https://en.wikipedia.org/wiki/Lamport_timestamp) | |
| Span | A series of continuous things | |
| Causal Order | The order of happen-before relationship | The DAG expresses the causal order of the changes |
| VV | [Version Vector](https://en.wikipedia.org/wiki/Version_vector) | |
| VV | [Version Vector](https://en.wikipedia.org/wiki/Version_vector) | In code, it has exclusive end, `VV {0: 8}` means the last op id of client 0 is `0-7` |
### RLE
@ -32,3 +32,9 @@ This gives us a compact way to represent the mergeable elements.
### Container
Each op is associated with one container. Different CRDT algorithms use different types of containers. There are hierarchical relationship between containers, but they cannot affect each other
# Convention
- There are methods like `id_last`, `id_end`, `lamport_last`, `lamport_end`. `last` refers to the last one, but
`end` refers to the exclusive end of a range. For example, OpSpan ranging from 0-0 till 0-8 has id_last of 0-8
and id_end of 0-9