use std::collections::BTreeMap;
use nodedb_wal::record::RecordType;
use crate::control::server::wal_dispatch_kv::encode::encode_kv_put;
use crate::data::executor::handlers::transaction::overlay::{Staged, StagedTtl, TxnOverlay};
use crate::data::executor::handlers::transaction::stage_write::unhex_key;
use crate::types::{DatabaseId, TenantId};
use crate::wal::RedoSubRecord;
const RESOLVE_TTL_MS: u64 = 0;
pub(super) fn serialize_kv_collection(
overlay: &TxnOverlay,
coll_key: &(DatabaseId, TenantId, String),
collection: &str,
ops: &mut Vec<RedoSubRecord>,
) -> crate::Result<()> {
let mut entries: BTreeMap<String, &Staged> = BTreeMap::new();
for (doc_id, staged) in overlay.iter_doc_entries_for_collection(coll_key) {
entries.insert(doc_id.to_string(), staged);
}
for (doc_id, staged) in entries {
let key = unhex_key(&doc_id).ok_or_else(|| crate::Error::Internal {
detail: format!("kv resolve: overlay doc-id '{doc_id}' is not valid hex"),
})?;
match staged {
Staged::Put(value) => {
let expire_at_ms = match overlay.get_ttl_by_doc_id(coll_key, &doc_id) {
Some(StagedTtl::ExpireAt(ms)) => Some(ms),
Some(StagedTtl::Persist) | None => None,
};
let payload = encode_kv_put(collection, &key, value, RESOLVE_TTL_MS, expire_at_ms)?;
ops.push(RedoSubRecord {
record_type: RecordType::Put as u32,
payload,
});
}
Staged::Tombstone => {
let payload = zerompk::to_msgpack_vec(&("kv_delete", collection, vec![key]))
.map_err(|e| crate::Error::Serialization {
format: "msgpack".into(),
detail: format!("kv resolve delete: {e}"),
})?;
ops.push(RedoSubRecord {
record_type: RecordType::Delete as u32,
payload,
});
}
}
}
Ok(())
}