view src/blockhandle.rs @ 387:2ac6eedcc9dc

db_impl: Use a BufWriter inside LogWriter Unbuffered write-a-lot with 32768 entries written, first four iterations on a new DB: usr=0.32 sys=0.12 elap=0.46 usr=0.47 sys=0.12 elap=0.60 usr=0.59 sys=0.11 elap=0.72 usr=0.50 sys=0.15 elap=0.67 Buffered write-a-lot with 32768 entries written, first four iterations on a new DB: usr=0.22 sys=0.01 elap=0.24 (delta = -0.1/-0.11/-0.22) usr=0.43 sys=0.03 elap=0.48 (delta = -0.04/-0.09/-0.12) usr=0.54 sys=0.05 elap=0.62 (delta = -0.05/-0.06/-0.1) usr=0.42 sys=0.03 elap=0.47 (delta = (-0.08/-0.12/-0.2)
author Lewin Bormann <lbo@spheniscida.de>
date Mon, 09 Oct 2017 05:51:43 +0000
parents 6e14c9e7e53d
children 9f01a2fbcda2
line wrap: on
line source

use integer_encoding::VarInt;

/// Contains an offset and a length (or size); can be efficiently encoded in to varints. This is
/// used typically as file-internal pointer in table (SSTable) files. For example, the index block
/// in an SSTable is a block of (key = largest key in block) -> (value = encoded blockhandle of
/// block).
#[derive(Debug, Clone)]
pub struct BlockHandle {
    offset: usize,
    size: usize,
}

impl BlockHandle {
    /// Decodes a block handle from `from` and returns a block handle
    /// together with how many bytes were read from the slice.
    pub fn decode(from: &[u8]) -> (BlockHandle, usize) {
        let (off, offsize) = usize::decode_var(from);
        let (sz, szsize) = usize::decode_var(&from[offsize..]);

        (BlockHandle {
            offset: off,
            size: sz,
        },
         offsize + szsize)
    }

    pub fn new(offset: usize, size: usize) -> BlockHandle {
        BlockHandle {
            offset: offset,
            size: size,
        }
    }

    pub fn offset(&self) -> usize {
        self.offset
    }

    pub fn size(&self) -> usize {
        self.size
    }

    /// Returns how many bytes were written, or 0 if the write failed because `dst` is too small.
    pub fn encode_to(&self, dst: &mut [u8]) -> usize {
        assert!(dst.len() >= self.offset.required_space() + self.size.required_space());

        let off = self.offset.encode_var(dst);
        off + self.size.encode_var(&mut dst[off..])
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_blockhandle() {
        let bh = BlockHandle::new(890, 777);
        let mut dst = [0 as u8; 128];
        let enc_sz = bh.encode_to(&mut dst[..]);

        let (bh2, dec_sz) = BlockHandle::decode(&dst);

        assert_eq!(enc_sz, dec_sz);
        assert_eq!(bh.size(), bh2.size());
        assert_eq!(bh.offset(), bh2.offset());
    }
}