use std::time::Duration;
use crate::shard::actor::{RangeItem, ShardError, ShardHandle};
use crate::tree::Hash;
use super::{DatabaseError, DbRange, ShardCommitResult};
pub(super) fn map_spawn_error(error: ShardError) -> DatabaseError {
match error {
ShardError::Spawn(message) => DatabaseError::ShardSpawn(message),
other => map_shard_error(other),
}
}
pub(super) fn map_shard_error(error: ShardError) -> DatabaseError {
match error {
ShardError::SequenceConflict { expected, actual } => {
DatabaseError::SequenceConflict { expected, actual }
}
ShardError::CasMismatch { expected, actual } => {
DatabaseError::CasMismatch { expected, actual }
}
ShardError::Spawn(message) => DatabaseError::ShardSpawn(message),
other => DatabaseError::ShardError(other.to_string()),
}
}
pub(super) fn ordered_hashes(
results: Vec<ShardCommitResult>,
shard_count: usize,
) -> Result<Vec<Hash>, DatabaseError> {
let mut ordered = vec![None; shard_count];
for (index, result) in results {
match result {
Ok(hash) => {
if let Some(slot) = ordered.get_mut(index) {
*slot = Some(hash);
}
}
Err(error) => return Err(map_shard_error(error)),
}
}
let mut hashes = Vec::with_capacity(shard_count);
for hash in ordered {
let Some(hash) = hash else {
return Err(DatabaseError::ShardError(
"missing shard commit result".to_owned(),
));
};
hashes.push(hash);
}
Ok(hashes)
}
pub(super) fn range_on_handle(
handle: &ShardHandle,
from: &[u8],
to: &[u8],
timeout: Duration,
) -> Result<DbRange, DatabaseError> {
let items = handle
.range(from.to_vec(), to.to_vec(), timeout)
.map_err(map_shard_error)?;
collect_range_items(items)
}
fn collect_range_items(items: Vec<RangeItem>) -> Result<DbRange, DatabaseError> {
let mut entries = Vec::new();
for item in items {
match item {
RangeItem::Entry { key, value } => entries.push((key, value)),
RangeItem::Done => return Ok(entries),
}
}
Err(DatabaseError::ShardError(
"range result missing Done".to_owned(),
))
}
pub(super) fn event_range_start(key: &[u8], seq: u64) -> Vec<u8> {
let mut encoded = Vec::with_capacity(key.len().saturating_add(9));
encoded.extend_from_slice(key);
encoded.push(0);
encoded.extend_from_slice(&seq.to_be_bytes());
encoded
}
pub(super) fn event_range_end(key: &[u8]) -> Vec<u8> {
let mut encoded = Vec::with_capacity(key.len().saturating_add(1));
encoded.extend_from_slice(key);
encoded.push(1);
encoded
}