/// Common trait for armdb collections managed by [`Db`](super::tree_db::Db).
///
/// Implemented for `TypedTree`, `TypedMap`, `ZeroTree`, `ZeroMap`
/// where the value type implements [`CollectionMeta`](crate::CollectionMeta).
pub trait Collection: Send + Sync {
    /// Collection name (from `CollectionMeta::NAME`).
    fn name(&self) -> &str;
    /// Number of entries in the collection.
    fn len(&self) -> usize;
    fn is_empty(&self) -> bool {
        self.len() == 0
    }
    /// Run a compaction pass across all shards.
    fn compact(&self) -> crate::DbResult<usize>;
    /// Flush in-memory write buffers and pending hint data so an immediate
    /// process exit will not lose committed writes. No default — every impl
    /// must provide this to avoid silent durability gaps.
    fn flush(&self) -> crate::DbResult<()>;
    /// Lightest operation that bounds the periodic durability window for
    /// background use. Backend-specific:
    /// - Bitcask: flush userspace write buffers to the OS page cache (no fsync,
    ///   no hint regeneration) — bounds process-crash (panic/kill/OOM) loss.
    /// - FixedStore: fdatasync dirty pages (data is already in the page cache
    ///   via pwrite) — bounds power-loss loss for idle tail writes.
    ///
    /// Unlike [`flush`](Self::flush), this must NOT rebuild hint files or fsync
    /// the active data file on Bitcask, so it is cheap enough to run on a short
    /// interval. No default — every impl must provide it.
    fn periodic_flush(&self) -> crate::DbResult<()>;
    /// Full clean shutdown for this collection. Heavier than [`flush`](Self::flush):
    /// - Bitcask/Var: flush write buffers, write hint files, fsync data files.
    /// - FixedStore: fdatasync data, write the `fixed.versions` sidecar and set
    ///   the clean-shutdown flag so the NEXT open takes Clean recovery.
    ///
    /// # Contract
    ///
    /// The caller must stop all application writers first. Any write after this
    /// call — a local mutation *or* a FixedStore replication-apply from a leader —
    /// downgrades the affected shard back to Dirty recovery (safe, slow); it never
    /// corrupts. Background [`periodic_flush`](Self::periodic_flush) and
    /// [`compact`](Self::compact) are not writes and are harmless afterwards.
    /// Idempotent; [`Db`](super::db::Db) drop after it keeps the clean state intact.
    ///
    /// # Comparison with other shutdown paths
    ///
    /// | Method | Bitcask hints | Fixed sidecar/clean-flag | Final fsync | Stops workers |
    /// |---|---|---|---|---|
    /// | [`periodic_flush`](Self::periodic_flush) (background) | no | no | no (Bitcask) / fdatasync (Fixed) | — |
    /// | [`Db::close`](super::db::Db::close) | writes hints | **no** | no / fdatasync | no |
    /// | [`Db::clean_shutdown`](super::db::Db::clean_shutdown) | writes hints | **yes** | yes | no (caller contract) |
    /// | [`Db::shutdown`](super::db::Db::shutdown) | via close | **no** | — | yes |
    fn clean_shutdown(&self) -> crate::DbResult<()>;
}
