/* Design:

  Master Map Table has fixed size records, each 2 x 64 bit numbers, root page and number of buckets.
  These numbers can change on any hash map insertion ( or deletion ), although changes are not frequent.

  Map 0 maps Names to a Map Info Record ( which is a varvarl ).

  A Map Info Record has the Map Id, the Map Name and possibly other info about the map.
*/

use crate::*;

/// Storage of Map numbers.
pub struct SysMap {
    pub t: Table,
}

impl SysMap {
    pub fn new((next_id, root, len): (u64, u64, u64)) -> Self {
        let rpp = 64;
        let t = Table {
            next_id,
            root,
            len,
            record_size: 8,
            rpp,
        };
        Self { t }
    }

    pub fn save(&self) -> (u64, u64, u64) {
        (self.t.next_id, self.t.root, self.t.len)
    }

    /// Get hash map (root, buckets) using id.
    pub fn get(&self, id: u64, ps: &mut PageSet) -> (u64, u64) {
        let mut buf = [0u8; 16];
        self.t.read(id, &mut buf, ps);
        let root = u64::from_le_bytes(buf[0..8].try_into().unwrap());
        let buckets = u64::from_le_bytes(buf[8..16].try_into().unwrap());
        (root, buckets)
    }

    /// Set (root, buckets) for id.
    pub fn set(&mut self, id: u64, (root, buckets): (u64, u64), ps: &mut PageSet) {
        let mut buf = [0u8; 16];

        buf[0..8].copy_from_slice(&root.to_le_bytes());
        buf[8..16].copy_from_slice(&buckets.to_le_bytes());

        self.t.update(id, &buf, ps);
    }
}
