///|
/// 帧号 -> 快照字节的环形缓冲。容量固定、按帧号取模寻址,
/// 槽位记录真实帧号,被覆盖后旧帧查询返回 `None`。
pub struct SnapshotRing {
capacity : Int32
frames : Array[Int32]
items : Array[Bytes?]
}
///|
pub fn SnapshotRing::new(capacity : Int32) -> SnapshotRing {
let cap = if capacity < 1 { 1 } else { capacity }
{
capacity: cap,
frames: Array::make(cap, -1),
items: Array::make(cap, None),
}
}
///|
pub fn SnapshotRing::capacity(self : SnapshotRing) -> Int32 {
self.capacity
}
///|
fn SnapshotRing::slot(self : SnapshotRing, frame : Int32) -> Int32 {
let m = frame % self.capacity
if m < 0 {
m + self.capacity
} else {
m
}
}
///|
pub fn SnapshotRing::set(
self : SnapshotRing,
frame : Int32,
bytes : Bytes,
) -> Unit {
let i = self.slot(frame)
self.frames[i] = frame
self.items[i] = Some(bytes)
}
///|
pub fn SnapshotRing::get(self : SnapshotRing, frame : Int32) -> Bytes? {
let i = self.slot(frame)
if self.frames[i] == frame {
self.items[i]
} else {
None
}
}
///|
/// 帧号 -> 状态哈希的环形缓冲。
///
/// 快照字节只用于重放,比较两端「已确认帧」的世界是否一致需要历史哈希;
/// 只比较当前帧会把两端各自不同的预测误判成分叉。
pub struct HashRing {
capacity : Int32
frames : Array[Int32]
items : Array[UInt64]
}
///|
pub fn HashRing::new(capacity : Int32) -> HashRing {
let cap = if capacity < 1 { 1 } else { capacity }
{ capacity: cap, frames: Array::make(cap, -1), items: Array::make(cap, 0UL), }
}
///|
fn HashRing::slot(self : HashRing, frame : Int32) -> Int32 {
let m = frame % self.capacity
if m < 0 {
m + self.capacity
} else {
m
}
}
///|
pub fn HashRing::set(self : HashRing, frame : Int32, hash : UInt64) -> Unit {
let i = self.slot(frame)
self.frames[i] = frame
self.items[i] = hash
}
///|
pub fn HashRing::get(self : HashRing, frame : Int32) -> UInt64? {
let i = self.slot(frame)
if self.frames[i] == frame {
Some(self.items[i])
} else {
None
}
}