All files / json-crdt-patch/codec/clock ClockTable.ts

97.5% Statements 39/40
0% Branches 0/1
100% Functions 9/9
100% Lines 35/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 6412x       12x   51246x 51246x       12x   1538x 1538x   24080x 1538x       1542x 1542x 1542x 24084x 1542x     3080x 3080x     68895x 68895x 68895x 68895x 68895x       51246x 51246x 51246x 51246x       279600x 279600x 279600x       1540x 1540x 1540x 1540x 25623x 25623x 25623x        
import {type ITimestampStruct, type IClockVector, Timestamp} from '../../clock';
import type {CrdtReader} from '../../util/binary/CrdtReader';
import type {CrdtWriter} from '../../util/binary/CrdtWriter';
 
export class ClockTableEntry {
  constructor(
    public index: number,
    public id: ITimestampStruct,
  ) {}
}
 
export class ClockTable {
  public static from(clock: IClockVector): ClockTable {
    const table = new ClockTable();
    table.push(new Timestamp(clock.sid, clock.time - 1));
    // biome-ignore lint: using .forEach() on Map is the fastest way to iterate
    clock.peers.forEach((id) => table.push(id));
    return table;
  }
 
  public static decode(reader: CrdtReader): ClockTable {
    const clockTable = new ClockTable();
    const length = reader.vu57();
    clockTable.push(new Timestamp(reader.vu57(), reader.vu57()));
    for (let i = 1; i < length; i++) clockTable.push(new Timestamp(reader.vu57(), reader.vu57()));
    return clockTable;
  }
 
  public readonly bySid: Map<number, ClockTableEntry> = new Map<number, ClockTableEntry>();
  public readonly byIdx: ITimestampStruct[] = [];
 
  public parseField(field: `${string}_${string}`): ITimestampStruct {
    const underscoreIndex = field.indexOf('_');
    const relativeSid = Number.parseInt(field.slice(0, underscoreIndex), 36);
    const time = Number.parseInt(field.slice(underscoreIndex + 1), 36);
    const clock = this.byIdx[relativeSid];
    return new Timestamp(clock.sid, time);
  }
 
  public push(id: ITimestampStruct): void {
    const byIdx = this.byIdx;
    const index = byIdx.length;
    byIdx.push(id);
    this.bySid.set(id.sid, new ClockTableEntry(index, id));
  }
 
  public getBySid(sid: number): ClockTableEntry {
    const entry = this.bySid.get(sid);
    Iif (!entry) throw new Error('CLOCK_NOT_FOUND');
    return entry;
  }
 
  public write(writer: CrdtWriter): void {
    const table = this.byIdx;
    const length = table.length;
    writer.vu57(length);
    for (let i = 0; i < length; i++) {
      const clock = table[i];
      writer.vu57(clock.sid);
      writer.vu57(clock.time);
    }
  }
}