Skip to content

Commit

Permalink
Optimize reading more than one dptr
Browse files Browse the repository at this point in the history
  • Loading branch information
JayKickliter committed Nov 2, 2023
1 parent f74630e commit 8f4bf44
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 11 deletions.
19 changes: 19 additions & 0 deletions src/disktree/dptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,25 @@ where
Ok(dptr)
}

/// Read 5 * `n` bytes from disk, for up to n=7, and parses them as
/// litte-endien `u64`s.
pub(crate) fn read_n<R>(src: &mut R, n: usize) -> Result<Vec<u64>>
where
R: Read + Seek,
{
assert!(n <= 7);
let mut buf = [0; DPTR_SZ * 7];
src.read_exact(&mut buf[..(DPTR_SZ * n)])?;
Ok(buf[..(DPTR_SZ * n)]
.chunks(DPTR_SZ)
.map(|chunk| {
let mut buf = [0u8; size_of::<u64>()];
buf[..DPTR_SZ].copy_from_slice(chunk);
u64::from_le_bytes(buf)
})
.collect())
}

/// Writes the 5 lower bytes of a `u64` to disk.
pub(crate) fn write<W>(dst: &mut W, dptr: u64) -> Result
where
Expand Down
20 changes: 9 additions & 11 deletions src/disktree/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,22 @@ where
fn read_node(&mut self, dptr: u64) -> Result<Node> {
self.seek_to(dptr)?;
let node_tag = self.rdr.read_u8()?;
let base_pos = self.rdr.stream_position()?;
let base_pos = dptr + std::mem::size_of_val(&node_tag) as u64;
debug_assert_eq!(base_pos, self.rdr.stream_position().unwrap());
assert!(node_tag == 0 || node_tag > 0b1000_0000);
let node = if node_tag == 0 {
Node::Leaf(base_pos)
if node_tag == 0 {
Ok(Node::Leaf(base_pos))
} else {
let mut buf = self.node_buf();
let n_children = (node_tag & 0b0111_1111).count_ones() as usize;
let mut child_dptrs = dptr::read_n(&mut self.rdr, n_children)?;
for digit in (0..7).rev() {
if node_tag & (1 << digit) != 0 {
let bit_cnt = (((node_tag as u16) << (8 - digit)) & 0xFF).count_ones();
let child_dptr_pos = base_pos + (bit_cnt as u64 * dptr::DPTR_SZ as u64);
self.seek_to(child_dptr_pos)?;
let child_dptr = dptr::read(&mut self.rdr)?;
buf.push((digit, child_dptr));
buf.push((digit, child_dptrs.pop().unwrap()));
}
}
Node::Parent(buf)
};
Ok(node)
Ok(Node::Parent(buf))
}
}

fn node_buf(&mut self) -> Vec<(u8, u64)> {
Expand Down

0 comments on commit 8f4bf44

Please sign in to comment.