tablestg 0.4.9

Storage for database tables
Documentation
use crate::*;

/// Storage of variable length values (varval).
struct VarValStore {
    tv: (u64, u64),
}

impl VarValStore {
    pub fn new(tv: (u64, u64)) -> Self {
        Self { tv }
    }

    pub fn save(&self) -> (u64, u64) {
        self.tv
    }

    /// Store a new varval, returns addr.
    pub fn store(&mut self, user_data: &[u8], ps: &mut PageSet) -> u64 {
        let mut tv = TreeVec::new(self.tv, ps);
        let result = self.tv.1;

        let elen = Self::encode_len( len, false );
        w.write( result, &elen );
        w.write( result + elen.len(), user_data );
        self.tv = tv.save();
        result
    }

    fn encode_len(len: usize, del: bool) -> LVec<u8>
    {
        let len = len as u64;
        let mut len = len * 2; // LSB is reserved for delete indicator
        if del { len += 1; }
        let result = LVec::new();
        loop
        {
            if len < 128 
            {
               result.push( len as u8 );
               break;
            }
            result.push( len as u8 + 128 );
            len = len / 128;
        }
        result
    }

    /// Reads a stored varval with given addr.
    pub fn get(&self, addr: u64, ps: &mut PageSet) -> LVec<u8> {
        let mut tv = TreeVec::new(self.tv, ps);
        let mut _rdr = treevec::Reader(tv);
        todo!(); // Read length and then bytes
    }

    /// Delete a stored varval with given id and len.
    pub fn delete(&mut self, _addr: u64, _len: usize, _ps: &mut PageSet) {
        // ToDo : increase free space
    }

    /// Update a varval, returns new id.
    ///
    /// Will re-use addr if length does not change.
    pub fn update(&mut self, addr: u64, old_len: usize, user_data: &[u8], ps: &mut PageSet) -> u64 {
        let mut tv = TreeVec::new(self.tv, ps);
        if old_len == user_data.len() {
            tv.write(addr, user_data);
            addr
        } else {
            self.delete(addr, old_len, ps);
            self.store(user_data, ps)
        }
    }
}

// ************** End VarVal

/// Address of stored variable length value ( varval ).
#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd)] // Comparison should really just be done on id.
pub struct VarValAddr {
    /// This will eventually be more complicated, e,g, may be a TreeVec, or diferent VarValStores.
    addr: u64,
}

impl VarValAddr {
    pub fn new(dt: &DataType, v: &Value, ps: &mut PageSet) -> Self {
        let bytes = dt.value_to_bytes(v);
        let mut vv = VarValStore::new(ps.vvs); // Will be multiple stores eventually.
        let addr = vv.store(&bytes, ps);
        ps.vvs = vv.save();

        Self { addr }
    }

    pub fn get(&self, dt: &DataType, ps: &mut PageSet) -> Value {
        let vv = VarValStore::new(ps.vvs);
        let mut buf = vec![0; self.len as usize];
        vv.get(self.addr, self.len as usize, &mut buf, ps);

        dt.bytes_to_value(&buf)
    }

    pub fn update(&self, dt: &DataType, v: &Value, ps: &mut PageSet) -> Self {
        let mut vv = VarValStore::new(ps.vvs);

        let bytes = dt.value_to_bytes(v);
        let len = bytes.len() as u64;
        let addr = vv.update(self.addr, self.len as usize, &bytes, ps);
        ps.vvs = vv.save();

        Self { addr, len }
    }

    pub fn delete(&self, ps: &mut PageSet) {
        let mut vv = VarValStore::new(ps.vvs);
        vv.delete(self.addr, self.len as usize, ps);
        ps.vvs = vv.save();
    }
}

impl SmallFixed for VarValAddr {
    fn size() -> usize {
        2 * 8
    }
    fn load(bytes: &[u8]) -> Self {
        let addr = u64::from_le_bytes(bytes[0..8].try_into().unwrap());
        let len = u64::from_le_bytes(bytes[8..16].try_into().unwrap());
        Self { addr, len }
    }
    fn save(&self, bytes: &mut [u8]) {
        bytes[0..8].copy_from_slice(&self.addr.to_le_bytes());
        bytes[8..16].copy_from_slice(&self.len.to_le_bytes());
    }
}

// ************** End VarValAddr

#[cfg(test)]
pub fn test_varval(ps: &mut PageSet) {
    let tv = (ps.new_page(), 0);
    let mut vv = VarValStore { tv };

    let mut ids = Vec::new();

    let d1 = b"Hello there George";
    let d2 = b"Tuesday is lovely, so is Wednesday";
    //let d2 = b"Tuesday is lovely! So is Wednesday. .............................................Saturday also.";
    for _ in 0..1_000_000 {
        let id = vv.store(d1, ps);
        ids.push(id);
        // println!("test varval stored {}", id);
        // println!("");
    }

    //println!("ids={:?}", ids);

    let mut buf = vec![0; d1.len()];
    for id in &ids {
        vv.get(*id, d1.len(), &mut buf, ps);
        // println!("buf={}", tos(&buf));
        assert_eq!(buf, d1);
    }

    let mut nids = Vec::new();
    for id in &ids {
        let nid = vv.update(*id, d1.len(), d2, ps);
        nids.push(nid);
    }

    let mut buf = vec![0; d2.len()];
    for id in &nids {
        vv.get(*id, d2.len(), &mut buf, ps);
        assert_eq!(buf, d2);
    }
}