diff --git a/src/core/codec.rs b/src/core/codec.rs index c4985adfe..d782cb40c 100644 --- a/src/core/codec.rs +++ b/src/core/codec.rs @@ -1,4 +1,5 @@ use core::serial::*; +use core::directory::WritePtr; use fst::MapBuilder; use std::io; use std::io::Error as IOError; @@ -44,9 +45,9 @@ pub struct SimpleCodec; pub struct SimpleSegmentSerializer { segment: Segment, written_bytes_postings: usize, - postings_write: File, + postings_write: WritePtr, store_writer: StoreWriter, - term_fst_builder: FstMapBuilder, // TODO find an alternative to work around the "move" + term_fst_builder: FstMapBuilder, // TODO find an alternative to work around the "move" encoder: simdcompression::Encoder, } @@ -97,9 +98,9 @@ impl SimpleCodec { // TODO skip lists // TODO make that part of the codec API pub fn serializer(segment: &Segment) -> Result { - let term_write = try!(segment.open_writable(SegmentComponent::TERMS)); - let postings_write = try!(segment.open_writable(SegmentComponent::POSTINGS)); - let store_write = try!(segment.open_writable(SegmentComponent::STORE)); + let term_write = try!(segment.open_write(SegmentComponent::TERMS)); + let postings_write = try!(segment.open_write(SegmentComponent::POSTINGS)); + let store_write = try!(segment.open_write(SegmentComponent::STORE)); let term_fst_builder_result = FstMapBuilder::new(term_write); let term_fst_builder = term_fst_builder_result.unwrap(); Ok(SimpleSegmentSerializer { diff --git a/src/core/directory2.rs b/src/core/directory.rs similarity index 84% rename from src/core/directory2.rs rename to src/core/directory.rs index 1cc13894f..6a1efce6c 100644 --- a/src/core/directory2.rs +++ b/src/core/directory.rs @@ -28,6 +28,12 @@ impl Deref for ReadOnlySource { type Target = [u8]; fn deref(&self) -> &[u8] { + self.as_slice() + } +} + +impl ReadOnlySource { + pub fn as_slice(&self,) -> &[u8] { match *self { ReadOnlySource::Mmap(ref mmap_read_only) => unsafe { mmap_read_only.as_slice() }, ReadOnlySource::Anonymous(ref shared_vec) => shared_vec.as_slice(), @@ -35,20 +41,22 @@ impl Deref for ReadOnlySource { } } -#[derive(Debug)] -pub enum CreateError { - RootDirectoryDoesNotExist, - DirectoryAlreadyExists, - CannotCreateTempDirectory(io::Error), -} +// +// #[derive(Debug)] +// pub enum CreateError { +// RootDirectoryDoesNotExist, +// DirectoryAlreadyExists, +// CannotCreateTempDirectory(io::Error), +// } pub trait Directory: fmt::Debug { fn open_read(&self, path: &Path) -> io::Result; fn open_write(&mut self, path: &Path) -> io::Result>; fn atomic_write(&mut self, path: &Path, data: &[u8]) -> io::Result<()>; + fn sync(&self, path: &Path) -> io::Result<()>; + fn sync_directory(&self,) -> io::Result<()>; } - pub type WritePtr = Box; @@ -71,9 +79,9 @@ impl fmt::Debug for MmapDirectory { impl MmapDirectory { - pub fn create_tempdir() -> Result { + pub fn create_from_tempdir() -> io::Result { // TODO error management - let tempdir = try!(TempDir::new("index").map_err(CreateError::CannotCreateTempDirectory)); + let tempdir = try!(TempDir::new("index")); let tempdir_path = PathBuf::from(tempdir.path()); let mut directory = MmapDirectory { root_path: PathBuf::from(tempdir_path), @@ -83,9 +91,8 @@ impl MmapDirectory { Ok(directory) } - pub fn create(filepath: &Path) -> Result { + pub fn create(filepath: &Path) -> io::Result { Ok(MmapDirectory { - root_path: PathBuf::from(filepath), mmap_cache: RefCell::new(HashMap::new()), _temp_directory: None @@ -95,6 +102,8 @@ impl MmapDirectory { fn resolve_path(&self, relative_path: &Path) -> PathBuf { self.root_path.join(relative_path) } + + } impl Directory for MmapDirectory { @@ -125,6 +134,15 @@ impl Directory for MmapDirectory { }); Ok(()) } + + fn sync(&self, path: &Path) -> io::Result<()> { + let full_path = self.resolve_path(path); + File::open(&full_path).and_then(|fd| fd.sync_all()) + } + + fn sync_directory(&self,) -> io::Result<()> { + File::open(&self.root_path).and_then(|fd| fd.sync_all()) + } } @@ -166,7 +184,7 @@ impl fmt::Debug for RAMDirectory { } impl RAMDirectory { - pub fn create() -> Result { + pub fn create() -> io::Result { Ok(RAMDirectory { fs: HashMap::new() }) @@ -198,6 +216,14 @@ impl Directory for RAMDirectory { }); Ok(()) } + + fn sync(&self, path: &Path) -> io::Result<()> { + Ok(()) + } + + fn sync_directory(&self,) -> io::Result<()> { + Ok(()) + } } @@ -217,7 +243,7 @@ mod tests { #[test] fn test_mmap_directory() { - let mut mmap_directory = MmapDirectory::create_tempdir().unwrap(); + let mut mmap_directory = MmapDirectory::create_from_tempdir().unwrap(); test_directory(&mut mmap_directory); } diff --git a/src/core/fstmap.rs b/src/core/fstmap.rs index 0b0e7a965..ba6272735 100644 --- a/src/core/fstmap.rs +++ b/src/core/fstmap.rs @@ -60,6 +60,22 @@ pub struct FstMap { impl FstMap { + pub fn from_bytes(data: Vec) -> io::Result> { + panic!("FstMap from bytes is not implemented"); + // let mut cursor = Cursor::new(data.as_slice()); + // try!(cursor.seek(io::SeekFrom::End(-4))); + // let footer_size = try!(u32::deserialize(&mut cursor)) as usize; + // let split_len = data.len() - 4 - footer_size; + // let fst_data = cpdata.slice(0, ); + // let values_mmap = mmap.range(split_len, footer_size); + // let fst = try!(fst::raw::Fst::from_mmap(fst_mmap).map_err(convert_fst_error)); + // Ok(FstMap { + // fst_index: fst::Map::from(fst), + // values_mmap: values_mmap, + // _phantom_: PhantomData, + // }) + } + pub fn open(mmap: MmapReadOnly) -> io::Result> { //let mmap = try!(MmapReadOnly::open(&file)); let mut cursor = Cursor::new(unsafe {mmap.as_slice()}); diff --git a/src/core/index.rs b/src/core/index.rs index a36f37775..f0c14593e 100644 --- a/src/core/index.rs +++ b/src/core/index.rs @@ -1,27 +1,24 @@ - use std::path::{PathBuf, Path}; use std::collections::HashMap; -use std::fs::File; use std::fs; +use std::io; use core::schema::Schema; -use std::collections::hash_map::Entry as HashMapEntry; use std::io::Write; use std::borrow::BorrowMut; use std::sync::{Arc, RwLock, RwLockWriteGuard, RwLockReadGuard}; use std::fmt; use std::cell::RefCell; use rand::{thread_rng, Rng}; -use fst::raw::MmapReadOnly; use rustc_serialize::json; -use atomicwrites; -use tempdir::TempDir; +use std::error; use std::io::Read; -use std::io::Error as IOError; use std::io::ErrorKind as IOErrorKind; +use core::directory::{Directory, MmapDirectory, RAMDirectory, ReadOnlySource, WritePtr}; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct SegmentId(pub String); + pub fn generate_segment_name() -> SegmentId { static CHARS: &'static [u8] = b"abcdefghijklmnopqrstuvwxyz0123456789"; let random_name: String = (0..8) @@ -53,32 +50,23 @@ impl IndexMeta { impl fmt::Debug for Index { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Index({:?})", self.inner_index.read().unwrap().index_path) + write!(f, "Index({:?})", self.directory) } } -fn open_mmap(full_path: &PathBuf) -> Result { - MmapReadOnly::open_path(full_path.clone()) -} - -fn sync_file(filepath: &PathBuf) -> Result<(), IOError> { - File::open(filepath.clone()) - .and_then(|fd| fd.sync_all()) -} - +type DirectoryPtr = Box; #[derive(Clone)] pub struct Index { metas: Arc>, - inner_index: Arc>, + directory: Arc>, } -pub enum CreateError { - RootIndexDoesNotExist, - IndexAlreadyExists, - CannotOpenMetaFile, +fn could_not_acquire_lock(e: E) -> io::Error { + io::Error::new(IOErrorKind::Other, "Could not acquire read lock on directory") } + struct IndexError; lazy_static! { @@ -87,61 +75,74 @@ lazy_static! { impl Index { - pub fn create(filepath: &Path, schema: Schema) -> Result { - let inner_index = try!(InnerIndex::create(filepath)); - Ok(Index::from_inner_index(inner_index, schema)) + pub fn create(directory_path: &Path, schema: Schema) -> io::Result { + let directory = Box::new(try!(MmapDirectory::create(directory_path))); + Ok(Index::from_directory(directory, schema)) } - pub fn create_from_tempdir(schema: Schema) -> Result { - let inner_index = try!(InnerIndex::create_from_tempdir()); - Ok(Index::from_inner_index(inner_index, schema)) + pub fn create_from_tempdir(schema: Schema) -> io::Result { + let directory = Box::new(try!(MmapDirectory::create_from_tempdir())); + Ok(Index::from_directory(directory, schema)) } - pub fn open>(filepath: &P) -> Result { - let inner_index = try!(InnerIndex::open(filepath)); - let mut index = Index::from_inner_index(inner_index, Schema::new()); + pub fn open(directory_path: &Path) -> io::Result { + let directory = try!(MmapDirectory::create(directory_path)); + let directory_ptr = Box::new(directory); + let mut index = Index::from_directory(directory_ptr, Schema::new()); try!(index.load_metas()); //< does the directory already exists? Ok(index) } + fn from_directory(directory: DirectoryPtr, schema: Schema) -> Index { + Index { + metas: Arc::new(RwLock::new(IndexMeta::with_schema(schema))), + directory: Arc::new(RwLock::new(directory)), + } + } + pub fn schema(&self,) -> Schema { self.metas.read().unwrap().schema.clone() } - fn get_write(&mut self) -> Result, IOError> { - self.inner_index + fn get_write(&mut self) -> io::Result> { + self.directory .write() - .map_err(|e| IOError::new(IOErrorKind::Other, + .map_err(|e| io::Error::new(IOErrorKind::Other, format!("Failed acquiring lock on directory.\n It can happen if another thread panicked! Error was: {:?}", e) )) } - fn get_read(&self) -> Result, IOError> { - self.inner_index + fn get_read(&self) -> io::Result> { + self.directory .read() - .map_err(|e| IOError::new(IOErrorKind::Other, + .map_err(|e| io::Error::new(IOErrorKind::Other, format!("Failed acquiring lock on directory.\n It can happen if another thread panicked! Error was: {:?}", e) )) } - fn from_inner_index(inner_index: InnerIndex, schema: Schema) -> Index { - Index { - metas: Arc::new(RwLock::new(IndexMeta::with_schema(schema))), - inner_index: Arc::new(RwLock::new(inner_index)), - } - } + // TODO find a rusty way to hide that, while keeping // it visible for IndexWriters. - pub fn publish_segment(&mut self, segment: Segment) -> Result<(), IOError> { + pub fn publish_segment(&mut self, segment: Segment) -> io::Result<()> { println!("publish segment {:?}", segment); self.metas.write().unwrap().segments.push(segment.segment_id.0.clone()); // TODO use logs self.save_metas() } - pub fn sync(&mut self, segment: Segment) -> Result<(), IOError> { - try!(self.get_write()).sync(segment) + pub fn sync(&mut self, segment: Segment) -> io::Result<()> { + for component in [SegmentComponent::POSTINGS, SegmentComponent::TERMS].iter() { + let path = segment.relative_path(component); + let directory = try!(self.directory + .read() + .map_err(could_not_acquire_lock)); + try!(directory.sync(&path)); + } + let directory = try!(self.directory + .read() + .map_err(could_not_acquire_lock)); + directory.sync_directory() } pub fn segments(&self,) -> Vec { @@ -175,111 +176,29 @@ impl Index { self.segment(&generate_segment_name()) } - - pub fn load_metas(&mut self,) -> Result<(), IOError> { - let meta_file = try!(self.inner_index.read().unwrap().mmap(&META_FILEPATH)); - let meta_content = String::from_utf8_lossy(unsafe {meta_file.as_slice()}); + pub fn load_metas(&mut self,) -> io::Result<()> { + let meta_file = try!( + self.directory + .read() + .map_err(could_not_acquire_lock) + .and_then(|d| d.open_read(&META_FILEPATH))); + let meta_content = String::from_utf8_lossy(meta_file.as_slice()); let loaded_meta: IndexMeta = json::decode(&meta_content).unwrap(); self.metas.write().unwrap().clone_from(&loaded_meta); Ok(()) } - pub fn save_metas(&self,) -> Result<(), IOError> { + pub fn save_metas(&self,) -> io::Result<()> { let metas_lock = self.metas.read().unwrap(); let encoded = json::encode(&*metas_lock).unwrap(); - self.inner_index.write().unwrap().write_atomic(&META_FILEPATH, encoded) + try!(self.directory + .write() + .map_err(could_not_acquire_lock) + ).atomic_write(&META_FILEPATH, encoded.as_bytes()) } } -struct InnerIndex { - index_path: PathBuf, - mmap_cache: RefCell>, - _temp_directory: Option, -} - - -fn create_tempdir() -> Result { - TempDir::new("index") -} - - -impl InnerIndex { - - - - pub fn write_atomic(&self, path: &PathBuf, data: String) -> Result<(), IOError> { - let meta_file = atomicwrites::AtomicFile::new(path, atomicwrites::AllowOverwrite); - meta_file.write(|f| { - f.write_all(data.as_bytes()) - }) - } - - pub fn create>(filepath: P) -> Result { - let filepath_os_path = filepath.as_ref().as_os_str(); - let directory = InnerIndex { - index_path: PathBuf::from(&filepath_os_path), - mmap_cache: RefCell::new(HashMap::new()), - _temp_directory: None, - }; - Ok(directory) - } - - pub fn create_from_tempdir() -> Result { - let tempdir = try!(create_tempdir()); - let tempdir_path = PathBuf::from(tempdir.path()); - let directory = InnerIndex { - index_path: PathBuf::from(tempdir_path), - mmap_cache: RefCell::new(HashMap::new()), - _temp_directory: Some(tempdir) - }; - Ok(directory) - } - - pub fn open>(filepath: &P) -> Result { - let directory = InnerIndex { - index_path: PathBuf::from(filepath.as_ref().as_os_str()), - mmap_cache: RefCell::new(HashMap::new()), - _temp_directory: None, - }; - Ok(directory) - } - - pub fn sync(&mut self, segment: Segment) -> Result<(), IOError> { - for component in [SegmentComponent::POSTINGS, SegmentComponent::TERMS].iter() { - let relative_path = segment.relative_path(component); - let full_path = self.resolve_path(&relative_path); - try!(sync_file(&full_path)); - } - // syncing the directory itself - sync_file(&self.index_path) - } - - fn resolve_path(&self, relative_path: &PathBuf) -> PathBuf { - self.index_path.join(relative_path) - } - - fn open_writable(&self, relative_path: &PathBuf) -> Result { - let full_path = self.resolve_path(relative_path); - File::create(full_path.clone()) - } - - fn mmap(&self, relative_path: &PathBuf) -> Result { - let full_path = self.resolve_path(relative_path); - let mut mmap_cache = self.mmap_cache.borrow_mut(); - Ok(match mmap_cache.entry(full_path.clone()) { - HashMapEntry::Occupied(e) => e.get().clone(), - HashMapEntry::Vacant(vacant_entry) => { - let new_mmap = try!(open_mmap(&full_path)); - vacant_entry.insert(new_mmap.clone()); - new_mmap - } - }) - } -} - - - ///////////////////////// // Segment @@ -296,8 +215,6 @@ pub struct Segment { segment_id: SegmentId, } - - impl Segment { pub fn id(&self,) -> SegmentId { @@ -306,8 +223,8 @@ impl Segment { fn path_suffix(component: &SegmentComponent)-> &'static str { match *component { - SegmentComponent::POSTINGS => ".idx", // SegmentComponent::POSITIONS => ".pos", + SegmentComponent::POSTINGS => ".idx", SegmentComponent::TERMS => ".term", SegmentComponent::STORE => ".store", } @@ -319,13 +236,13 @@ impl Segment { PathBuf::from(filename) } - pub fn mmap(&self, component: SegmentComponent) -> Result { + pub fn open_read(&self, component: SegmentComponent) -> io::Result { let path = self.relative_path(&component); - self.index.inner_index.read().unwrap().mmap(&path) + self.index.directory.read().unwrap().open_read(&path) } - pub fn open_writable(&self, component: SegmentComponent) -> Result { + pub fn open_write(&self, component: SegmentComponent) -> io::Result { let path = self.relative_path(&component); - self.index.inner_index.write().unwrap().open_writable(&path) + self.index.directory.write().unwrap().open_write(&path) } } diff --git a/src/core/mod.rs b/src/core/mod.rs index d836ab706..e33809c7a 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,6 +1,6 @@ pub mod postings; pub mod schema; -// pub mod directory; +pub mod directory; pub mod writer; pub mod analyzer; pub mod serial; diff --git a/src/core/reader.rs b/src/core/reader.rs index aaea95c3c..c074ebce7 100644 --- a/src/core/reader.rs +++ b/src/core/reader.rs @@ -6,7 +6,9 @@ use fst; use core::postings::IntersectionPostings; use byteorder::{BigEndian, ReadBytesExt}; use core::serialize::BinarySerializable; +use core::directory::ReadOnlySource; use std::io::Cursor; +use fst::raw::Fst; use core::schema::DocId; use core::index::SegmentComponent; use fst::raw::MmapReadOnly; @@ -23,7 +25,7 @@ use core::fstmap::FstMap; pub struct SegmentReader { segment: Segment, term_offsets: FstMap, - postings_data: MmapReadOnly, + postings_data: ReadOnlySource, store_reader: StoreReader, } @@ -94,6 +96,14 @@ impl Iterator for SegmentPostings { } } + +fn open_fst_map(source: ReadOnlySource) -> io::Result> { + match source { + ReadOnlySource::Mmap(mmap) => FstMap::open(mmap), + ReadOnlySource::Anonymous(data) => FstMap::from_bytes(data), + } +} + impl SegmentReader { pub fn id(&self,) -> SegmentId { @@ -101,10 +111,10 @@ impl SegmentReader { } pub fn open(segment: Segment) -> Result { - let term_shared_mmap = try!(segment.mmap(SegmentComponent::TERMS)); - let term_offsets = try!(FstMap::open(term_shared_mmap)); - let store_reader = StoreReader::new(try!(segment.mmap(SegmentComponent::STORE))); - let postings_shared_mmap = try!(segment.mmap(SegmentComponent::POSTINGS)); + let term_shared_mmap = try!(segment.open_read(SegmentComponent::TERMS)); + let term_offsets = try!(open_fst_map(term_shared_mmap)); + let store_reader = StoreReader::new(try!(segment.open_read(SegmentComponent::STORE))); + let postings_shared_mmap = try!(segment.open_read(SegmentComponent::POSTINGS)); Ok(SegmentReader { postings_data: postings_shared_mmap, term_offsets: term_offsets, diff --git a/src/core/store.rs b/src/core/store.rs index 4fbd6a699..8ff48f8e5 100644 --- a/src/core/store.rs +++ b/src/core/store.rs @@ -1,17 +1,18 @@ use std::io::BufWriter; -use std::fs::File; +use core::directory::WritePtr; use std::cell::RefCell; use core::schema::DocId; use core::schema::Document; use core::schema::FieldValue; +use std::ops::DerefMut; use core::serialize::BinarySerializable; +use core::directory::ReadOnlySource; use std::io::Write; use std::io::Read; use std::io::Cursor; use std::io::Error as IOError; use std::io; use std::io::SeekFrom; -use fst::raw::MmapReadOnly; use std::io::Seek; use lz4; @@ -23,7 +24,7 @@ pub struct StoreWriter { doc: DocId, offsets: Vec, // TODO have a better index. written: u64, - writer: BufWriter, + writer: WritePtr, intermediary_buffer: Vec, current_block: Vec, } @@ -45,12 +46,12 @@ impl BinarySerializable for OffsetIndex { impl StoreWriter { - pub fn new(file: File) -> StoreWriter { + pub fn new(writer: WritePtr) -> StoreWriter { StoreWriter { doc: 0, written: 0, offsets: Vec::new(), - writer: BufWriter::new(file), + writer: writer, intermediary_buffer: Vec::new(), current_block: Vec::new(), } @@ -93,6 +94,7 @@ impl StoreWriter { self.write_and_compress_block(); } let header_offset: u64 = self.written; + //let writer_mutref: &mut Write = self.writer.deref_mut(); self.offsets.serialize(&mut self.writer); header_offset.serialize(&mut self.writer); self.writer.flush() @@ -102,13 +104,13 @@ impl StoreWriter { pub struct StoreReader { - data: MmapReadOnly, + data: ReadOnlySource, offsets: Vec, current_block: RefCell>, } impl StoreReader { - fn read_header(data: &MmapReadOnly) -> Vec { + fn read_header(data: &ReadOnlySource) -> Vec { // todo err let mut cursor = Cursor::new(unsafe {data.as_slice()} ); cursor.seek(SeekFrom::End(-8)); @@ -160,7 +162,7 @@ impl StoreReader { Document::from(field_values) } - pub fn new(data: MmapReadOnly) -> StoreReader { + pub fn new(data: ReadOnlySource) -> StoreReader { let offsets = StoreReader::read_header(&data); StoreReader { data: data, @@ -180,21 +182,19 @@ mod tests { use rand::SeedableRng; use rand::StdRng; use std::io::Write; - use tempfile; + use std::path::PathBuf; use core::schema::Schema; use core::schema::FieldOptions; use core::schema::FieldValue; - use fst::raw::MmapReadOnly; - use std::fs::File; + use core::directory::{RAMDirectory, Directory, MmapDirectory, WritePtr, ReadOnlySource}; - - fn write_lorem_ipsum_store(store_file: File) -> Schema { + fn write_lorem_ipsum_store(writer: WritePtr) -> Schema { let mut schema = Schema::new(); let field_body = schema.add_field("body", &FieldOptions::new().set_stored()); let field_title = schema.add_field("title", &FieldOptions::new().set_stored()); let lorem = String::from("Doc Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."); { - let mut store_writer = StoreWriter::new(store_file); + let mut store_writer = StoreWriter::new(writer); for i in 0..1000 { let mut fields: Vec = Vec::new(); { @@ -219,14 +219,17 @@ mod tests { } schema } - #[test] + + #[test] fn test_store() { - let store_file = tempfile::NamedTempFile::new().unwrap(); - let mut schema = write_lorem_ipsum_store(store_file.reopen().unwrap()); + let path = PathBuf::from("store"); + let mut directory = RAMDirectory::create().unwrap(); + let store_file = directory.open_write(&path).unwrap(); + let mut schema = write_lorem_ipsum_store(store_file); let field_title = schema.field("title").unwrap(); - let store_mmap = MmapReadOnly::open(&store_file).unwrap(); - let store = StoreReader::new(store_mmap); + let store_source = directory.open_read(&path).unwrap(); + let store = StoreReader::new(store_source); for i in (0..10).map(|i| i * 3 / 2) { assert_eq!(*store.get(&i).get_one(&field_title).unwrap(), format!("Doc {}", i)); } @@ -234,23 +237,24 @@ mod tests { #[bench] fn bench_store_encode(b: &mut Bencher) { - let mut store_file = tempfile::NamedTempFile::new().unwrap(); + let mut directory = MmapDirectory::create_from_tempdir().unwrap(); + let path = PathBuf::from("store"); b.iter(|| { - write_lorem_ipsum_store(store_file.reopen().unwrap()); + write_lorem_ipsum_store(directory.open_write(&path).unwrap()); }); } - #[bench] - fn bench_store_decode(b: &mut Bencher) { + #[bench] + fn bench_store_decode(b: &mut Bencher) { + let mut directory = MmapDirectory::create_from_tempdir().unwrap(); + let path = PathBuf::from("store"); + write_lorem_ipsum_store(directory.open_write(&path).unwrap()); + let store_source = directory.open_read(&path).unwrap(); + let store = StoreReader::new(store_source); + b.iter(|| { + store.get(&12); + }); - let store_file = tempfile::NamedTempFile::new().unwrap(); - write_lorem_ipsum_store(store_file.reopen().unwrap()); - let store_mmap = MmapReadOnly::open(&store_file).unwrap(); - let store = StoreReader::new(store_mmap); - b.iter(|| { - store.get(&12); - }); - - } + } }