///|
/// Result of validating every manifest reference and Segment checksum.
pub(all) struct IndexCheckReport {
generation : Int
segment_count : Int
live_document_count : Int
orphan_files : ReadOnlyArray[String]
temporary_files : ReadOnlyArray[String]
} derive(Eq, @debug.Debug)
///|
/// Validates the current manifest, every referenced Segment, tombstones,
/// checksums, and cross-Segment Schema compatibility. Orphans and temporary
/// files are reported without making the otherwise valid snapshot unreadable.
pub fn[D : DirectoryV2] check_index(
directory : D,
) -> IndexCheckReport raise PersistenceError {
guard Directory::exists(directory, manifest_file_name) else {
raise PersistenceError::NotFound(manifest_file_name)
}
let manifest = decode_manifest(Directory::read(directory, manifest_file_name))
let mut live_document_count = 0
let mut schema : Schema? = None
for index in 0.. FaultInjectingDirectory[D] {
guard fail_at_operation > 0 else { abort("fault operation must be positive") }
{ inner, fail_at_operation, operation_count: 0 }
}
///|
fn[D] FaultInjectingDirectory::before_mutation(
self : FaultInjectingDirectory[D],
) -> Unit raise PersistenceError {
self.operation_count += 1
if self.operation_count == self.fail_at_operation {
raise PersistenceError::Io(
"injected directory failure at operation \{self.operation_count}",
)
}
}
///|
pub fn[D] FaultInjectingDirectory::operation_count(
self : FaultInjectingDirectory[D],
) -> Int {
self.operation_count
}
///|
pub impl[D : Directory] Directory for FaultInjectingDirectory[D] with fn write(
self,
name,
bytes,
) {
self.before_mutation()
Directory::write(self.inner, name, bytes)
}
///|
pub impl[D : Directory] Directory for FaultInjectingDirectory[D] with fn read(
self,
name,
) {
Directory::read(self.inner, name)
}
///|
pub impl[D : Directory] Directory for FaultInjectingDirectory[D] with fn exists(
self,
name,
) {
Directory::exists(self.inner, name)
}
///|
pub impl[D : DirectoryV2] DirectoryV2 for FaultInjectingDirectory[D] with fn write_atomic(
self,
name,
bytes,
) {
self.before_mutation()
DirectoryV2::write_atomic(self.inner, name, bytes)
}
///|
pub impl[D : DirectoryV2] DirectoryV2 for FaultInjectingDirectory[D] with fn sync(
self,
name,
) {
self.before_mutation()
DirectoryV2::sync(self.inner, name)
}
///|
pub impl[D : DirectoryV2] DirectoryV2 for FaultInjectingDirectory[D] with fn remove(
self,
name,
) {
self.before_mutation()
DirectoryV2::remove(self.inner, name)
}
///|
pub impl[D : DirectoryV2] DirectoryV2 for FaultInjectingDirectory[D] with fn list(
self,
) {
DirectoryV2::list(self.inner)
}
///|
pub impl[D : DirectoryV2] DirectoryV2 for FaultInjectingDirectory[D] with fn try_acquire_lock(
self,
name,
) {
self.before_mutation()
DirectoryV2::try_acquire_lock(self.inner, name)
}
///|
pub impl[D : DirectoryV2] DirectoryV2 for FaultInjectingDirectory[D] with fn release_lock(
self,
name,
token,
) {
self.before_mutation()
DirectoryV2::release_lock(self.inner, name, token)
}
///|
pub impl[D : DirectoryV2] DirectoryV2 for FaultInjectingDirectory[D] with fn capabilities(
self,
) {
DirectoryV2::capabilities(self.inner)
}