///|
fn snapshot_record_order(
left : IndexSnapshotRecord,
right : IndexSnapshotRecord,
) -> Int {
if left.record.id < right.record.id {
-1
} else if left.record.id > right.record.id {
1
} else {
0
}
}
///|
/// Exports a canonical version-one snapshot sorted by record identifier.
pub fn NameIndex::export_snapshot(self : NameIndex) -> IndexSnapshot {
let snapshot_records : Array[IndexSnapshotRecord] = []
for entry in self.records.to_array() {
let record = entry.1
let normalized = match self.normalized.get(record.id) {
Some(value) => value
None => ""
}
let bucket_keys = match self.record_bucket_keys.get(record.id) {
Some(value) => value.copy()
None => []
}
snapshot_records.push({ record, normalized, bucket_keys })
}
snapshot_records.sort_by(snapshot_record_order)
{
version: 1,
config: self.config,
blocking_algorithms: self.blocking_algorithms.copy(),
records: snapshot_records,
}
}
///|
fn snapshot_contains_id(
records : Array[IndexSnapshotRecord],
before : Int,
id : String,
) -> Bool {
for index = 0; index < before; index = index + 1 {
if records[index].record.id == id {
return true
}
}
false
}
///|
/// Rebuilds an index and verifies every supplied derived field by recomputation.
pub fn NameIndex::from_snapshot(
snapshot : IndexSnapshot,
) -> Result[NameIndex, IndexError] {
if snapshot.version != 1 {
return Err(UnsupportedSnapshotVersion(snapshot.version))
}
let index = match
NameIndex::new(snapshot.config, snapshot.blocking_algorithms) {
Err(error) => return Err(error)
Ok(value) => value
}
for record_index = 0
record_index < snapshot.records.length()
record_index = record_index + 1 {
let source = snapshot.records[record_index]
if snapshot_contains_id(snapshot.records, record_index, source.record.id) {
return Err(DuplicateSnapshotRecord(source.record.id))
}
match index.insert(source.record.id, source.record.name) {
Err(error) => return Err(error)
Ok(_) => ()
}
let recomputed_normalized = match index.normalized.get(source.record.id) {
Some(value) => value
None => return Err(InconsistentSnapshotRecord(source.record.id))
}
let recomputed_keys = match index.record_bucket_keys.get(source.record.id) {
Some(value) => value
None => return Err(InconsistentSnapshotRecord(source.record.id))
}
if recomputed_normalized != source.normalized ||
recomputed_keys != source.bucket_keys {
return Err(InconsistentSnapshotRecord(source.record.id))
}
}
Ok(index)
}