///|
/// KeyEntry metadata representing a record's location on disk.
pub struct KeyEntry {
  file_id : Int
  value_sz : Int
  value_pos : Int64
  timestamp : Int64
  expires_at : Int64
}

///|
/// Creates a new KeyEntry.
pub fn KeyEntry::new(
  file_id : Int,
  value_sz : Int,
  value_pos : Int64,
  timestamp : Int64,
  expires_at : Int64,
) -> KeyEntry {
  { file_id, value_sz, value_pos, timestamp, expires_at }
}

///|
/// In-memory key directory mapping keys to their metadata.
pub struct Keydir {
  mut entries : Map[String, KeyEntry]
}

///|
/// Creates a new Keydir.
pub fn Keydir::new() -> Keydir {
  { entries: Map([]) }
}

///|
/// Inserts a KeyEntry into the directory.
pub fn Keydir::put(self : Keydir, key : String, entry : KeyEntry) -> Unit {
  self.entries.set(key, entry)
}

///|
/// Retrieves a KeyEntry from the directory.
pub fn Keydir::get(self : Keydir, key : String) -> KeyEntry? {
  self.entries.get(key)
}

///|
/// Removes a key from the directory.
pub fn Keydir::delete(self : Keydir, key : String) -> Unit {
  self.entries.remove(key)
}

///|
/// Checks if the directory contains a key.
pub fn Keydir::contains(self : Keydir, key : String) -> Bool {
  self.entries.contains(key)
}

///|
/// Clears all entries from the directory.
pub fn Keydir::clear(self : Keydir) -> Unit {
  self.entries = Map([])
}

///|
/// Returns all keys in the directory.
pub fn Keydir::keys(self : Keydir) -> Array[String] {
  let keys = Array::new()
  for k, _ in self.entries {
    keys.push(k)
  }
  keys
}