diff --git a/sstable/src/dictionary.rs b/sstable/src/dictionary.rs index 6a76a1e94..718c547da 100644 --- a/sstable/src/dictionary.rs +++ b/sstable/src/dictionary.rs @@ -14,11 +14,8 @@ use itertools::Itertools; use tantivy_fst::Automaton; use tantivy_fst::automaton::AlwaysMatch; -use crate::sstable_index_v3::SSTableIndexV3Empty; use crate::streamer::{Streamer, StreamerBuilder}; -use crate::{ - BlockAddr, DeltaReader, Reader, SSTable, SSTableIndex, SSTableIndexV3, TermOrdinal, VoidSSTable, -}; +use crate::{BlockAddr, DeltaReader, Reader, SSTable, SSTableIndex, TermOrdinal, VoidSSTable}; /// An SSTable is a sorted map that associates sorted `&[u8]` keys /// to any kind of typed values. @@ -288,33 +285,7 @@ impl Dictionary { let (sstable_slice, index_slice) = main_slice.split(index_offset as usize); let sstable_index_bytes = index_slice.read_bytes()?; - let sstable_index = match version { - 2 => SSTableIndex::V2( - crate::sstable_index_v2::SSTableIndex::load(sstable_index_bytes).map_err(|_| { - io::Error::new(io::ErrorKind::InvalidData, "SSTable corruption") - })?, - ), - 3 => { - let (sstable_index_bytes, mut footerv3_len_bytes) = sstable_index_bytes.rsplit(8); - let store_offset = u64::deserialize(&mut footerv3_len_bytes)?; - if store_offset != 0 { - SSTableIndex::V3( - SSTableIndexV3::load(sstable_index_bytes, store_offset).map_err(|_| { - io::Error::new(io::ErrorKind::InvalidData, "SSTable corruption") - })?, - ) - } else { - // if store_offset is zero, there is no index, so we build a pseudo-index - // assuming a single block of sstable covering everything. - SSTableIndex::V3Empty(SSTableIndexV3Empty::load(index_offset as usize)) - } - } - _ => { - return Err(io::Error::other(format!( - "Unsupported sstable version, expected one of [2, 3], found {version}" - ))); - } - }; + let sstable_index = SSTableIndex::open(version, index_offset, sstable_index_bytes)?; Ok(Dictionary { sstable_slice, diff --git a/sstable/src/index/mod.rs b/sstable/src/index/mod.rs new file mode 100644 index 000000000..a4aff603e --- /dev/null +++ b/sstable/src/index/mod.rs @@ -0,0 +1,311 @@ +pub(crate) mod v2; +pub(crate) mod v3; + +use std::io::{self, Read, Write}; +use std::ops::Range; + +use common::{BinarySerializable, FixedSize, OwnedBytes}; +use tantivy_fst::{Automaton, MapBuilder}; + +use crate::{TermOrdinal, common_prefix_len}; + +#[derive(Debug, Clone)] +pub enum SSTableIndex { + V2(v2::SSTableIndex), + V3(v3::SSTableIndexV3), + V3Empty(v3::SSTableIndexV3Empty), +} + +impl SSTableIndex { + pub(crate) fn open( + version: u32, + index_offset: u64, + index_bytes: OwnedBytes, + ) -> io::Result { + let index = match version { + 2 => { + SSTableIndex::V2(v2::SSTableIndex::load(index_bytes).map_err(|_| { + io::Error::new(io::ErrorKind::InvalidData, "SSTable corruption") + })?) + } + 3 => { + let (index_bytes, mut footerv3_len_bytes) = index_bytes.rsplit(8); + let store_offset = u64::deserialize(&mut footerv3_len_bytes)?; + if store_offset != 0 { + SSTableIndex::V3(v3::SSTableIndexV3::load(index_bytes, store_offset).map_err( + |_| io::Error::new(io::ErrorKind::InvalidData, "SSTable corruption"), + )?) + } else { + // if store_offset is zero, there is no index, so we build a pseudo-index + // assuming a single block of sstable covering everything. + SSTableIndex::V3Empty(v3::SSTableIndexV3Empty::load(index_offset as usize)) + } + } + _ => { + return Err(io::Error::other(format!( + "Unsupported sstable version, expected one of [2, 3], found {version}" + ))); + } + }; + Ok(index) + } + + /// Get the [`BlockAddr`] of the requested block. + pub(crate) fn get_block(&self, block_id: u64) -> Option { + match self { + SSTableIndex::V2(v2_index) => v2_index.get_block(block_id as usize), + SSTableIndex::V3(v3_index) => v3_index.get_block(block_id), + SSTableIndex::V3Empty(v3_empty) => v3_empty.get_block(block_id), + } + } + + /// Get the block id of the block that would contain `key`. + /// + /// Returns None if `key` is lexicographically after the last key recorded. + pub(crate) fn locate_with_key(&self, key: &[u8]) -> Option { + match self { + SSTableIndex::V2(v2_index) => v2_index.locate_with_key(key).map(|i| i as u64), + SSTableIndex::V3(v3_index) => v3_index.locate_with_key(key), + SSTableIndex::V3Empty(v3_empty) => v3_empty.locate_with_key(key), + } + } + + /// Get the [`BlockAddr`] of the block that would contain `key`. + /// + /// Returns None if `key` is lexicographically after the last key recorded. + pub fn get_block_with_key(&self, key: &[u8]) -> Option { + match self { + SSTableIndex::V2(v2_index) => v2_index.get_block_with_key(key), + SSTableIndex::V3(v3_index) => v3_index.get_block_with_key(key), + SSTableIndex::V3Empty(v3_empty) => v3_empty.get_block_with_key(key), + } + } + + pub(crate) fn locate_with_ord(&self, ord: TermOrdinal) -> u64 { + match self { + SSTableIndex::V2(v2_index) => v2_index.locate_with_ord(ord) as u64, + SSTableIndex::V3(v3_index) => v3_index.locate_with_ord(ord), + SSTableIndex::V3Empty(v3_empty) => v3_empty.locate_with_ord(ord), + } + } + + /// Get the [`BlockAddr`] of the block containing the `ord`-th term. + pub(crate) fn get_block_with_ord(&self, ord: TermOrdinal) -> BlockAddr { + match self { + SSTableIndex::V2(v2_index) => v2_index.get_block_with_ord(ord), + SSTableIndex::V3(v3_index) => v3_index.get_block_with_ord(ord), + SSTableIndex::V3Empty(v3_empty) => v3_empty.get_block_with_ord(ord), + } + } + + pub fn get_block_for_automaton<'a>( + &'a self, + automaton: &'a impl Automaton, + ) -> impl Iterator + 'a { + match self { + SSTableIndex::V2(v2_index) => { + BlockIter::V2(v2_index.get_block_for_automaton(automaton)) + } + SSTableIndex::V3(v3_index) => { + BlockIter::V3(v3_index.get_block_for_automaton(automaton)) + } + SSTableIndex::V3Empty(v3_empty) => { + BlockIter::V3Empty(std::iter::once((0, v3_empty.block_addr.clone()))) + } + } + } +} + +enum BlockIter { + V2(V2), + V3(V3), + V3Empty(std::iter::Once), +} + +impl, V3: Iterator, T> Iterator for BlockIter { + type Item = T; + + fn next(&mut self) -> Option { + match self { + BlockIter::V2(v2) => v2.next(), + BlockIter::V3(v3) => v3.next(), + BlockIter::V3Empty(once) => once.next(), + } + } +} + +#[derive(Clone, Eq, PartialEq, Debug)] +pub struct BlockAddr { + pub first_ordinal: u64, + pub byte_range: Range, +} + +impl BlockAddr { + fn to_block_start(&self) -> BlockStartAddr { + BlockStartAddr { + first_ordinal: self.first_ordinal, + byte_range_start: self.byte_range.start, + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +struct BlockStartAddr { + first_ordinal: u64, + byte_range_start: usize, +} + +impl BlockStartAddr { + fn to_block_addr(&self, byte_range_end: usize) -> BlockAddr { + BlockAddr { + first_ordinal: self.first_ordinal, + byte_range: self.byte_range_start..byte_range_end, + } + } +} + +#[derive(Debug, Clone)] +pub(crate) struct BlockMeta { + /// Any byte string that is lexicographically greater or equal to + /// the last key in the block, + /// and yet strictly smaller than the first key in the next block. + pub last_key_or_greater: Vec, + pub block_addr: BlockAddr, +} + +impl BinarySerializable for BlockStartAddr { + fn serialize(&self, writer: &mut W) -> io::Result<()> { + let start = self.byte_range_start as u64; + start.serialize(writer)?; + self.first_ordinal.serialize(writer) + } + + fn deserialize(reader: &mut R) -> io::Result { + let byte_range_start = u64::deserialize(reader)? as usize; + let first_ordinal = u64::deserialize(reader)?; + Ok(BlockStartAddr { + first_ordinal, + byte_range_start, + }) + } + + // Provided method + fn num_bytes(&self) -> u64 { + BlockStartAddr::SIZE_IN_BYTES as u64 + } +} + +impl FixedSize for BlockStartAddr { + const SIZE_IN_BYTES: usize = 2 * u64::SIZE_IN_BYTES; +} + +/// Given that left < right, +/// mutates `left into a shorter byte string left'` that +/// matches `left <= left' < right`. +fn find_shorter_str_in_between(left: &mut Vec, right: &[u8]) { + assert!(&left[..] < right); + let common_len = common_prefix_len(left, right); + if left.len() == common_len { + return; + } + // It is possible to do one character shorter in some case, + // but it is not worth the extra complexity + for pos in (common_len + 1)..left.len() { + if left[pos] != u8::MAX { + left[pos] += 1; + left.truncate(pos + 1); + return; + } + } +} + +#[derive(Default)] +pub struct SSTableIndexBuilder { + blocks: Vec, +} + +impl SSTableIndexBuilder { + /// In order to make the index as light as possible, we + /// try to find a shorter alternative to the last key of the last block + /// that is still smaller than the next key. + pub(crate) fn shorten_last_block_key_given_next_key(&mut self, next_key: &[u8]) { + if let Some(last_block) = self.blocks.last_mut() { + find_shorter_str_in_between(&mut last_block.last_key_or_greater, next_key); + } + } + + pub fn add_block(&mut self, last_key: &[u8], byte_range: Range, first_ordinal: u64) { + self.blocks.push(BlockMeta { + last_key_or_greater: last_key.to_vec(), + block_addr: BlockAddr { + byte_range, + first_ordinal, + }, + }) + } + + pub fn serialize(&self, wrt: W) -> io::Result { + if self.blocks.len() <= 1 { + return Ok(0); + } + let counting_writer = common::CountingWriter::wrap(wrt); + let mut map_builder = MapBuilder::new(counting_writer).map_err(fst_error_to_io_error)?; + for (i, block) in self.blocks.iter().enumerate() { + map_builder + .insert(&block.last_key_or_greater, i as u64) + .map_err(fst_error_to_io_error)?; + } + let counting_writer = map_builder.into_inner().map_err(fst_error_to_io_error)?; + let written_bytes = counting_writer.written_bytes(); + let mut wrt = counting_writer.finish(); + + let mut block_store_writer = v3::BlockAddrStoreWriter::new(); + for block in &self.blocks { + block_store_writer.write_block_meta(block.block_addr.clone())?; + } + block_store_writer.serialize(&mut wrt)?; + + Ok(written_bytes) + } +} + +fn fst_error_to_io_error(error: tantivy_fst::Error) -> io::Error { + match error { + tantivy_fst::Error::Fst(fst_error) => io::Error::other(fst_error), + tantivy_fst::Error::Io(ioerror) => ioerror, + } +} + +#[cfg(test)] +mod tests { + #[track_caller] + fn test_find_shorter_str_in_between_aux(left: &[u8], right: &[u8]) { + let mut left_buf = left.to_vec(); + super::find_shorter_str_in_between(&mut left_buf, right); + assert!(left_buf.len() <= left.len()); + assert!(left <= &left_buf); + assert!(&left_buf[..] < right); + } + + #[test] + fn test_find_shorter_str_in_between() { + test_find_shorter_str_in_between_aux(b"", b"hello"); + test_find_shorter_str_in_between_aux(b"abc", b"abcd"); + test_find_shorter_str_in_between_aux(b"abcd", b"abd"); + test_find_shorter_str_in_between_aux(&[0, 0, 0], &[1]); + test_find_shorter_str_in_between_aux(&[0, 0, 0], &[0, 0, 1]); + test_find_shorter_str_in_between_aux(&[0, 0, 255, 255, 255, 0u8], &[0, 1]); + } + + use proptest::prelude::*; + + proptest! { + #![proptest_config(ProptestConfig::with_cases(100))] + #[test] + fn test_proptest_find_shorter_str(left in any::>(), right in any::>()) { + if left < right { + test_find_shorter_str_in_between_aux(&left, &right); + } + } + } +} diff --git a/sstable/src/sstable_index_v2.rs b/sstable/src/index/v2.rs similarity index 100% rename from sstable/src/sstable_index_v2.rs rename to sstable/src/index/v2.rs diff --git a/sstable/src/sstable_index_v3.rs b/sstable/src/index/v3.rs similarity index 73% rename from sstable/src/sstable_index_v3.rs rename to sstable/src/index/v3.rs index d6ef19bb4..b7c6673ed 100644 --- a/sstable/src/sstable_index_v3.rs +++ b/sstable/src/index/v3.rs @@ -1,106 +1,14 @@ use std::io::{self, Read, Write}; -use std::ops::Range; use std::sync::Arc; use common::{BinarySerializable, FixedSize, OwnedBytes}; use tantivy_bitpacker::{BitPacker, compute_num_bits}; use tantivy_fst::raw::Fst; -use tantivy_fst::{Automaton, IntoStreamer, Map, MapBuilder, Streamer}; +use tantivy_fst::{Automaton, IntoStreamer, Map, Streamer}; +use super::{BlockAddr, BlockStartAddr}; use crate::block_match_automaton::can_block_match_automaton; -use crate::{SSTableDataCorruption, TermOrdinal, common_prefix_len}; - -#[derive(Debug, Clone)] -pub enum SSTableIndex { - V2(crate::sstable_index_v2::SSTableIndex), - V3(SSTableIndexV3), - V3Empty(SSTableIndexV3Empty), -} - -impl SSTableIndex { - /// Get the [`BlockAddr`] of the requested block. - pub(crate) fn get_block(&self, block_id: u64) -> Option { - match self { - SSTableIndex::V2(v2_index) => v2_index.get_block(block_id as usize), - SSTableIndex::V3(v3_index) => v3_index.get_block(block_id), - SSTableIndex::V3Empty(v3_empty) => v3_empty.get_block(block_id), - } - } - - /// Get the block id of the block that would contain `key`. - /// - /// Returns None if `key` is lexicographically after the last key recorded. - pub(crate) fn locate_with_key(&self, key: &[u8]) -> Option { - match self { - SSTableIndex::V2(v2_index) => v2_index.locate_with_key(key).map(|i| i as u64), - SSTableIndex::V3(v3_index) => v3_index.locate_with_key(key), - SSTableIndex::V3Empty(v3_empty) => v3_empty.locate_with_key(key), - } - } - - /// Get the [`BlockAddr`] of the block that would contain `key`. - /// - /// Returns None if `key` is lexicographically after the last key recorded. - pub fn get_block_with_key(&self, key: &[u8]) -> Option { - match self { - SSTableIndex::V2(v2_index) => v2_index.get_block_with_key(key), - SSTableIndex::V3(v3_index) => v3_index.get_block_with_key(key), - SSTableIndex::V3Empty(v3_empty) => v3_empty.get_block_with_key(key), - } - } - - pub(crate) fn locate_with_ord(&self, ord: TermOrdinal) -> u64 { - match self { - SSTableIndex::V2(v2_index) => v2_index.locate_with_ord(ord) as u64, - SSTableIndex::V3(v3_index) => v3_index.locate_with_ord(ord), - SSTableIndex::V3Empty(v3_empty) => v3_empty.locate_with_ord(ord), - } - } - - /// Get the [`BlockAddr`] of the block containing the `ord`-th term. - pub(crate) fn get_block_with_ord(&self, ord: TermOrdinal) -> BlockAddr { - match self { - SSTableIndex::V2(v2_index) => v2_index.get_block_with_ord(ord), - SSTableIndex::V3(v3_index) => v3_index.get_block_with_ord(ord), - SSTableIndex::V3Empty(v3_empty) => v3_empty.get_block_with_ord(ord), - } - } - - pub fn get_block_for_automaton<'a>( - &'a self, - automaton: &'a impl Automaton, - ) -> impl Iterator + 'a { - match self { - SSTableIndex::V2(v2_index) => { - BlockIter::V2(v2_index.get_block_for_automaton(automaton)) - } - SSTableIndex::V3(v3_index) => { - BlockIter::V3(v3_index.get_block_for_automaton(automaton)) - } - SSTableIndex::V3Empty(v3_empty) => { - BlockIter::V3Empty(std::iter::once((0, v3_empty.block_addr.clone()))) - } - } - } -} - -enum BlockIter { - V2(V2), - V3(V3), - V3Empty(std::iter::Once), -} - -impl, V3: Iterator, T> Iterator for BlockIter { - type Item = T; - - fn next(&mut self) -> Option { - match self { - BlockIter::V2(v2) => v2.next(), - BlockIter::V3(v3) => v3.next(), - BlockIter::V3Empty(once) => once.next(), - } - } -} +use crate::{SSTableDataCorruption, TermOrdinal}; #[derive(Debug, Clone)] pub struct SSTableIndexV3 { @@ -216,7 +124,7 @@ impl Iterator for GetBlockForAutomaton<'_, A> { #[derive(Debug, Clone)] pub struct SSTableIndexV3Empty { - block_addr: BlockAddr, + pub block_addr: BlockAddr, } impl SSTableIndexV3Empty { @@ -257,147 +165,6 @@ impl SSTableIndexV3Empty { self.block_addr.clone() } } -#[derive(Clone, Eq, PartialEq, Debug)] -pub struct BlockAddr { - pub first_ordinal: u64, - pub byte_range: Range, -} - -impl BlockAddr { - fn to_block_start(&self) -> BlockStartAddr { - BlockStartAddr { - first_ordinal: self.first_ordinal, - byte_range_start: self.byte_range.start, - } - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -struct BlockStartAddr { - first_ordinal: u64, - byte_range_start: usize, -} - -impl BlockStartAddr { - fn to_block_addr(&self, byte_range_end: usize) -> BlockAddr { - BlockAddr { - first_ordinal: self.first_ordinal, - byte_range: self.byte_range_start..byte_range_end, - } - } -} - -#[derive(Debug, Clone)] -pub(crate) struct BlockMeta { - /// Any byte string that is lexicographically greater or equal to - /// the last key in the block, - /// and yet strictly smaller than the first key in the next block. - pub last_key_or_greater: Vec, - pub block_addr: BlockAddr, -} - -impl BinarySerializable for BlockStartAddr { - fn serialize(&self, writer: &mut W) -> io::Result<()> { - let start = self.byte_range_start as u64; - start.serialize(writer)?; - self.first_ordinal.serialize(writer) - } - - fn deserialize(reader: &mut R) -> io::Result { - let byte_range_start = u64::deserialize(reader)? as usize; - let first_ordinal = u64::deserialize(reader)?; - Ok(BlockStartAddr { - first_ordinal, - byte_range_start, - }) - } - - // Provided method - fn num_bytes(&self) -> u64 { - BlockStartAddr::SIZE_IN_BYTES as u64 - } -} - -impl FixedSize for BlockStartAddr { - const SIZE_IN_BYTES: usize = 2 * u64::SIZE_IN_BYTES; -} - -/// Given that left < right, -/// mutates `left into a shorter byte string left'` that -/// matches `left <= left' < right`. -fn find_shorter_str_in_between(left: &mut Vec, right: &[u8]) { - assert!(&left[..] < right); - let common_len = common_prefix_len(left, right); - if left.len() == common_len { - return; - } - // It is possible to do one character shorter in some case, - // but it is not worth the extra complexity - for pos in (common_len + 1)..left.len() { - if left[pos] != u8::MAX { - left[pos] += 1; - left.truncate(pos + 1); - return; - } - } -} - -#[derive(Default)] -pub struct SSTableIndexBuilder { - blocks: Vec, -} - -impl SSTableIndexBuilder { - /// In order to make the index as light as possible, we - /// try to find a shorter alternative to the last key of the last block - /// that is still smaller than the next key. - pub(crate) fn shorten_last_block_key_given_next_key(&mut self, next_key: &[u8]) { - if let Some(last_block) = self.blocks.last_mut() { - find_shorter_str_in_between(&mut last_block.last_key_or_greater, next_key); - } - } - - pub fn add_block(&mut self, last_key: &[u8], byte_range: Range, first_ordinal: u64) { - self.blocks.push(BlockMeta { - last_key_or_greater: last_key.to_vec(), - block_addr: BlockAddr { - byte_range, - first_ordinal, - }, - }) - } - - pub fn serialize(&self, wrt: W) -> io::Result { - if self.blocks.len() <= 1 { - return Ok(0); - } - let counting_writer = common::CountingWriter::wrap(wrt); - let mut map_builder = MapBuilder::new(counting_writer).map_err(fst_error_to_io_error)?; - for (i, block) in self.blocks.iter().enumerate() { - map_builder - .insert(&block.last_key_or_greater, i as u64) - .map_err(fst_error_to_io_error)?; - } - let counting_writer = map_builder.into_inner().map_err(fst_error_to_io_error)?; - let written_bytes = counting_writer.written_bytes(); - let mut wrt = counting_writer.finish(); - - let mut block_store_writer = BlockAddrStoreWriter::new(); - for block in &self.blocks { - block_store_writer.write_block_meta(block.block_addr.clone())?; - } - block_store_writer.serialize(&mut wrt)?; - - Ok(written_bytes) - } -} - -fn fst_error_to_io_error(error: tantivy_fst::Error) -> io::Error { - match error { - tantivy_fst::Error::Fst(fst_error) => io::Error::other(fst_error), - tantivy_fst::Error::Io(ioerror) => ioerror, - } -} const STORE_BLOCK_LEN: usize = 128; @@ -647,14 +414,14 @@ fn binary_search(max: u64, cmp_fn: impl Fn(u64) -> std::cmp::Ordering) -> Result Err(left) } -struct BlockAddrStoreWriter { +pub(crate) struct BlockAddrStoreWriter { buffer_block_metas: Vec, buffer_addrs: Vec, block_addrs: Vec, } impl BlockAddrStoreWriter { - fn new() -> Self { + pub(crate) fn new() -> Self { BlockAddrStoreWriter { buffer_block_metas: Vec::new(), buffer_addrs: Vec::new(), @@ -662,7 +429,7 @@ impl BlockAddrStoreWriter { } } - fn flush_block(&mut self) -> io::Result<()> { + pub(crate) fn flush_block(&mut self) -> io::Result<()> { if self.block_addrs.is_empty() { return Ok(()); } @@ -741,7 +508,7 @@ impl BlockAddrStoreWriter { Ok(()) } - fn write_block_meta(&mut self, block_addr: BlockAddr) -> io::Result<()> { + pub(crate) fn write_block_meta(&mut self, block_addr: BlockAddr) -> io::Result<()> { self.block_addrs.push(block_addr); if self.block_addrs.len() >= STORE_BLOCK_LEN { self.flush_block()?; @@ -749,7 +516,7 @@ impl BlockAddrStoreWriter { Ok(()) } - fn serialize(&mut self, wrt: &mut W) -> io::Result<()> { + pub(crate) fn serialize(&mut self, wrt: &mut W) -> io::Result<()> { self.flush_block()?; let len = self.buffer_block_metas.len() as u64; len.serialize(wrt)?; @@ -824,8 +591,9 @@ mod tests { use common::OwnedBytes; use super::*; - use crate::SSTableDataCorruption; use crate::block_match_automaton::tests::EqBuffer; + use crate::index::BlockMeta; + use crate::{SSTableDataCorruption, SSTableIndexBuilder}; #[test] fn test_sstable_index() { @@ -874,36 +642,7 @@ mod tests { assert!(matches!(data_corruption_err, SSTableDataCorruption)); } - #[track_caller] - fn test_find_shorter_str_in_between_aux(left: &[u8], right: &[u8]) { - let mut left_buf = left.to_vec(); - super::find_shorter_str_in_between(&mut left_buf, right); - assert!(left_buf.len() <= left.len()); - assert!(left <= &left_buf); - assert!(&left_buf[..] < right); - } - - #[test] - fn test_find_shorter_str_in_between() { - test_find_shorter_str_in_between_aux(b"", b"hello"); - test_find_shorter_str_in_between_aux(b"abc", b"abcd"); - test_find_shorter_str_in_between_aux(b"abcd", b"abd"); - test_find_shorter_str_in_between_aux(&[0, 0, 0], &[1]); - test_find_shorter_str_in_between_aux(&[0, 0, 0], &[0, 0, 1]); - test_find_shorter_str_in_between_aux(&[0, 0, 255, 255, 255, 0u8], &[0, 1]); - } - - use proptest::prelude::*; - - proptest! { - #![proptest_config(ProptestConfig::with_cases(100))] - #[test] - fn test_proptest_find_shorter_str(left in any::>(), right in any::>()) { - if left < right { - test_find_shorter_str_in_between_aux(&left, &right); - } - } - } + // use proptest::prelude::*; #[test] fn test_find_best_slop() { diff --git a/sstable/src/lib.rs b/sstable/src/lib.rs index 775d41d6a..1f6bd14c7 100644 --- a/sstable/src/lib.rs +++ b/sstable/src/lib.rs @@ -47,9 +47,8 @@ pub mod merge; mod streamer; pub mod value; -mod sstable_index_v3; -pub use sstable_index_v3::{BlockAddr, SSTableIndex, SSTableIndexBuilder, SSTableIndexV3}; -mod sstable_index_v2; +mod index; +pub use index::{BlockAddr, SSTableIndex, SSTableIndexBuilder}; pub(crate) mod vint; pub use dictionary::{Dictionary, TermOrdHit}; pub use streamer::{Streamer, StreamerBuilder};