From: Chris Mikkelson Date: Wed, 7 Aug 2024 22:13:17 +0000 (-0600) Subject: Give ReaderIter a Reader Clone for flexibility X-Git-Url: https://git.mikk.net/?a=commitdiff_plain;h=dcc7e4f6d86b1c29c3b4c34c13083f56b64ddc2a;p=mtbl-rs Give ReaderIter a Reader Clone for flexibility --- diff --git a/src/metadata.rs b/src/metadata.rs index df08ce9..ea5ee16 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -20,7 +20,7 @@ use std::mem::size_of; const MTBL_MAGIC: u32 = 0x4D54424C; -#[derive(Default)] +#[derive(Default, Clone)] pub(crate) struct Metadata { pub(crate) index_block_offset: usize, pub(crate) data_block_size: usize, diff --git a/src/reader/block.rs b/src/reader/block.rs index b2bf25c..72d5558 100644 --- a/src/reader/block.rs +++ b/src/reader/block.rs @@ -45,12 +45,14 @@ pub(crate) struct Block> { impl> Block { pub(crate) fn new(data: DataSlice) -> Result { + println!("Block::new( {:?} )", data.as_ref()); if data.as_ref().len() < size_of::() { return Err("block data too short".into()); } let rc_off = data.as_ref().len() - size_of::(); let restart_count = u32::from_be_bytes(data.as_ref()[rc_off..].try_into()?) as usize; + println!("restart_count = {}", restart_count); // try 32-bit restarts if (restart_count * size_of::()) > rc_off { diff --git a/src/reader/mod.rs b/src/reader/mod.rs index 4e11787..939ee6b 100644 --- a/src/reader/mod.rs +++ b/src/reader/mod.rs @@ -2,7 +2,7 @@ use crate::metadata::Metadata; use crate::source::{DefaultSource, IterSource}; use crate::Entry; use crate::Iter; -use integer_encoding::{FixedInt, VarInt}; +use integer_encoding::VarInt; pub(crate) mod block; use std::io::{Cursor, Seek, SeekFrom}; use std::sync::Arc; @@ -15,6 +15,16 @@ pub(crate) struct DataSlice> { len: usize, } +impl> Clone for DataSlice { + fn clone(&self) -> Self { + Self { + data: self.data.clone(), + off: self.off, + len: self.len, + } + } +} + impl> AsRef<[u8]> for DataSlice { fn as_ref(&self) -> &[u8] { &((*self.data).as_ref())[self.off..self.off + self.len] @@ -59,6 +69,15 @@ pub struct Reader> { metadata: Metadata, } +impl> Clone for Reader { + fn clone(&self) -> Self { + Self { + data: self.data.clone(), + metadata: self.metadata.clone(), + } + } +} + impl> Reader { pub fn new(d: D) -> Self { let mut cur = Cursor::new(&d.as_ref()[d.as_ref().len() - 512..]); @@ -80,25 +99,14 @@ impl> Reader { } } -pub struct ReaderIter<'r, D: AsRef<[u8]>> { - reader: &'r Reader, +pub struct ReaderIter> { + reader: Reader, next_offset: usize, index_iter: block::BlockIter, data_iter: Option>, } -impl> Reader { - pub fn iter(&self) -> ReaderIter<'_, D> { - ReaderIter { - reader: self, - next_offset: 0, - index_iter: self.index_iter(), - data_iter: None, - } - } -} - -impl<'r, D: AsRef<[u8]>> ReaderIter<'r, D> { +impl> ReaderIter { fn next_block(&mut self) -> Option<()> { if self.next_offset >= self.reader.metadata.index_block_offset { return None; @@ -107,6 +115,10 @@ impl<'r, D: AsRef<[u8]>> ReaderIter<'r, D> { .expect("bad block size"); let crc_off = self.next_offset + len_size; let data_off = crc_off + std::mem::size_of::(); + println!( + "Block: {};{}, data_off = {}", + self.next_offset, size, data_off + ); let _crc = u32::from_be_bytes( self.reader.data.as_ref()[crc_off..crc_off + 4] .try_into() @@ -122,7 +134,7 @@ impl<'r, D: AsRef<[u8]>> ReaderIter<'r, D> { } } -impl<'r, D: AsRef<[u8]>> Iterator for ReaderIter<'r, D> { +impl> Iterator for ReaderIter { type Item = Entry; fn next(&mut self) -> Option { if self.data_iter.is_none() { @@ -140,7 +152,7 @@ impl<'r, D: AsRef<[u8]>> Iterator for ReaderIter<'r, D> { } } -impl<'r, D: AsRef<[u8]>> Iter for ReaderIter<'r, D> { +impl> Iter for ReaderIter { fn seek(&mut self, key: &[u8]) { // TODO: detect and skip unneeded seek in iter. self.index_iter.seek(key); @@ -154,11 +166,11 @@ impl<'r, D: AsRef<[u8]>> Iter for ReaderIter<'r, D> { } } -impl<'r, D: AsRef<[u8]>> IterSource for &'r Reader { - type It = ReaderIter<'r, D>; +impl> IterSource for Reader { + type It = ReaderIter; fn iter(&self) -> Self::It { ReaderIter { - reader: self, + reader: self.clone(), next_offset: 0, index_iter: self.index_iter(), data_iter: None, @@ -166,4 +178,4 @@ impl<'r, D: AsRef<[u8]>> IterSource for &'r Reader { } } -impl<'r, D: AsRef<[u8]>> DefaultSource for &'r Reader {} +impl> DefaultSource for Reader {} diff --git a/tests/rwtest.rs b/tests/rwtest.rs index a378f21..6dde2ce 100644 --- a/tests/rwtest.rs +++ b/tests/rwtest.rs @@ -1,5 +1,6 @@ use mtbl::entry::Entry; use mtbl::reader::Reader; +use mtbl::source::IterSource; use mtbl::writer::Writer; #[test] @@ -16,7 +17,6 @@ fn test_write_readback() { } assert!(store.len() > 512); - let r = Reader::new(&store); - let ri = r.iter(); + let ri = Reader::new(&store).iter(); assert_eq!(ri.collect::>(), reference); }