diff --git a/nomt/src/beatree/mod.rs b/nomt/src/beatree/mod.rs index 82dff579..c594e727 100644 --- a/nomt/src/beatree/mod.rs +++ b/nomt/src/beatree/mod.rs @@ -133,7 +133,7 @@ impl Tree { }) } - /// Lookup a key in the btree. + /// Lookup a key in the btree. This blocks the current thread. pub fn lookup(&self, key: Key) -> Option> { let shared = self.shared.read(); @@ -148,7 +148,7 @@ impl Tree { } // Finally, look up in the btree. - ops::lookup( + ops::lookup_blocking( key, &shared.bbn_index, &shared.leaf_cache, @@ -574,7 +574,11 @@ impl ReadTransaction { }; match self.load_leaf_async(leaf_pn, io_handle, user_data) { - Ok(leaf) => Ok(ops::finish_lookup(key, &leaf.inner, &self.inner.leaf_store)), + Ok(leaf) => Ok(ops::finish_lookup_blocking( + key, + &leaf.inner, + &self.inner.leaf_store, + )), Err(pending) => Err(AsyncLookup(key, pending)), } } @@ -631,7 +635,7 @@ impl AsyncLookup { /// Calling this with the wrong page will likely lead to panics or bugs in the future. pub fn finish(self, page: FatPage) -> Option> { let leaf = self.1.finish_inner(page); - ops::finish_lookup(self.0, &leaf, &self.1.read_tx.leaf_store) + ops::finish_lookup_blocking(self.0, &leaf, &self.1.read_tx.leaf_store) } } diff --git a/nomt/src/beatree/ops/mod.rs b/nomt/src/beatree/ops/mod.rs index f697f470..6b4323dd 100644 --- a/nomt/src/beatree/ops/mod.rs +++ b/nomt/src/beatree/ops/mod.rs @@ -32,19 +32,23 @@ pub fn partial_lookup(key: Key, bbn_index: &Index) -> Option { search_branch(&branch, key.clone()).map(|(_, leaf_pn)| leaf_pn) } -/// Finish looking up a key in a leaf node. -pub fn finish_lookup(key: Key, leaf: &LeafNode, leaf_store: &StoreReader) -> Option> { +/// Finish looking up a key in a leaf node using blocking I/O. +pub fn finish_lookup_blocking( + key: Key, + leaf: &LeafNode, + leaf_store: &StoreReader, +) -> Option> { leaf.get(&key).map(|(v, is_overflow)| { if is_overflow { - overflow::read(v, leaf_store) + overflow::read_blocking(v, leaf_store) } else { v.to_vec() } }) } -/// Lookup a key in the btree. -pub fn lookup( +/// Lookup a key in the btree using blocking I/O. +pub fn lookup_blocking( key: Key, bbn_index: &Index, leaf_cache: &LeafCache, @@ -66,7 +70,7 @@ pub fn lookup( } }; - Ok(finish_lookup(key, &leaf, leaf_store)) + Ok(finish_lookup_blocking(key, &leaf, leaf_store)) } /// Binary search a branch node for the child node containing the key. This returns the last child diff --git a/nomt/src/beatree/ops/overflow.rs b/nomt/src/beatree/ops/overflow.rs index 310e80ca..68c12122 100644 --- a/nomt/src/beatree/ops/overflow.rs +++ b/nomt/src/beatree/ops/overflow.rs @@ -170,8 +170,8 @@ fn needed_pages(size: usize) -> usize { (size + BODY_SIZE - 1) / BODY_SIZE } -/// Read a large value from pages referenced by an overflow cell. -pub fn read(cell: &[u8], leaf_reader: &StoreReader) -> Vec { +/// Read a large value from pages referenced by an overflow cell using blocking I/O. +pub fn read_blocking(cell: &[u8], leaf_reader: &StoreReader) -> Vec { let (value_size, _, cell_pages) = decode_cell(cell); let total_pages = total_needed_pages(value_size); @@ -182,7 +182,7 @@ pub fn read(cell: &[u8], leaf_reader: &StoreReader) -> Vec { for i in 0..total_pages { let page = leaf_reader.query(page_numbers[i]); - let (page_pns, bytes) = read_page(&page); + let (page_pns, bytes) = parse_page(&page); page_numbers.extend(page_pns); value.extend(bytes); } @@ -194,6 +194,8 @@ pub fn read(cell: &[u8], leaf_reader: &StoreReader) -> Vec { } /// Iterate all pages related to an overflow cell and push onto a free-list. +/// +/// This only logically deletes the pages. pub fn delete(cell: &[u8], leaf_reader: &StoreReader, freed: &mut Vec) { let (value_size, _, cell_pages) = decode_cell(cell); let total_pages = total_needed_pages(value_size); @@ -203,7 +205,7 @@ pub fn delete(cell: &[u8], leaf_reader: &StoreReader, freed: &mut Vec(page: &'a FatPage) -> (impl Iterator + 'a, &'a [u8]) { +fn parse_page<'a>(page: &'a FatPage) -> (impl Iterator + 'a, &'a [u8]) { let n_pages = u16::from_le_bytes(page[0..2].try_into().unwrap()) as usize; let n_bytes = u16::from_le_bytes(page[2..4].try_into().unwrap()) as usize; diff --git a/nomt/src/io/mod.rs b/nomt/src/io/mod.rs index bbcb9b23..c1f77537 100644 --- a/nomt/src/io/mod.rs +++ b/nomt/src/io/mod.rs @@ -3,7 +3,7 @@ std::compile_error!("NOMT only supports Unix-based OSs"); use crossbeam_channel::{Receiver, RecvError, SendError, Sender, TryRecvError}; use page_pool::Page; -use std::{fmt, fs::File, os::fd::RawFd}; +use std::{fmt, fs::File, io::IoSliceMut, os::fd::RawFd}; #[cfg(target_os = "linux")] #[path = "linux.rs"]