use std::collections::VecDeque;
use linkrs_core::types::Timestamp;
use linkrs_transaction::types::WriteSet;
const COMMITTED_WRITE_SET_CAPACITY: usize = 512;
const MAX_PUBLISHED_WRITE_SET_SIZE: usize = 8192;
pub(crate) struct CommittedWriteSetWindow {
entries: parking_lot::Mutex<VecDeque<(Timestamp, WriteSet)>>,
}
impl CommittedWriteSetWindow {
pub(crate) fn new() -> Self {
Self {
entries: parking_lot::Mutex::new(VecDeque::new()),
}
}
pub(crate) fn has_conflict(&self, local: &WriteSet, read_ts: Timestamp) -> bool {
if local.is_empty() {
return false;
}
let entries = self.entries.lock();
entries.iter().any(|(commit_ts, committed)| {
*commit_ts > read_ts && local.has_conflict_with(committed)
})
}
pub(crate) fn publish(&self, commit_ts: Timestamp, write_set: WriteSet, horizon: Timestamp) {
if write_set.is_empty() || write_set.size() > MAX_PUBLISHED_WRITE_SET_SIZE {
return;
}
let mut entries = self.entries.lock();
entries.push_back((commit_ts, write_set));
while entries.len() > COMMITTED_WRITE_SET_CAPACITY {
entries.pop_front();
}
while entries.len() > 1
&& entries
.front()
.is_some_and(|(ts, _)| *ts <= horizon && horizon != u64::MAX)
{
entries.pop_front();
}
}
}