mirror of
https://github.com/neondatabase/neon.git
synced 2026-10-29 06:56:47 +00:00
ordered-vec and seqsizes
This commit is contained in:
@@ -63,6 +63,7 @@ use bookfile::{Book, BookWriter};
|
||||
|
||||
use zenith_utils::bin_ser::BeSer;
|
||||
use zenith_utils::lsn::Lsn;
|
||||
use zenith_utils::ordered_vec::OrderedVec;
|
||||
|
||||
use super::blob::{read_blob, BlobRange};
|
||||
|
||||
@@ -147,7 +148,7 @@ pub struct DeltaLayerInner {
|
||||
page_version_metas: BTreeMap<(u32, Lsn), BlobRange>,
|
||||
|
||||
/// `relsizes` tracks the size of the relation at different points in time.
|
||||
relsizes: BTreeMap<Lsn, u32>,
|
||||
relsizes: OrderedVec<Lsn, u32>,
|
||||
}
|
||||
|
||||
impl Layer for DeltaLayer {
|
||||
@@ -268,10 +269,10 @@ impl Layer for DeltaLayer {
|
||||
|
||||
// Scan the BTreeMap backwards, starting from the given entry.
|
||||
let inner = self.load()?;
|
||||
let mut iter = inner.relsizes.range((Included(&Lsn(0)), Included(&lsn)));
|
||||
let slice = inner.relsizes.range((Included(&Lsn(0)), Included(&lsn)));
|
||||
|
||||
let result;
|
||||
if let Some((_entry_lsn, entry)) = iter.next_back() {
|
||||
if let Some((_entry_lsn, entry)) = slice.last() {
|
||||
result = *entry;
|
||||
// Use the base image if needed
|
||||
} else if let Some(predecessor) = &self.predecessor {
|
||||
@@ -300,7 +301,7 @@ impl Layer for DeltaLayer {
|
||||
fn unload(&self) -> Result<()> {
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
inner.page_version_metas = BTreeMap::new();
|
||||
inner.relsizes = BTreeMap::new();
|
||||
inner.relsizes = OrderedVec::default();
|
||||
inner.loaded = false;
|
||||
Ok(())
|
||||
}
|
||||
@@ -404,7 +405,7 @@ impl DeltaLayer {
|
||||
inner: Mutex::new(DeltaLayerInner {
|
||||
loaded: true,
|
||||
page_version_metas: BTreeMap::new(),
|
||||
relsizes,
|
||||
relsizes: OrderedVec::from(relsizes),
|
||||
}),
|
||||
predecessor,
|
||||
};
|
||||
@@ -442,7 +443,7 @@ impl DeltaLayer {
|
||||
|
||||
// and relsizes to separate chapter
|
||||
let mut chapter = book.new_chapter(REL_SIZES_CHAPTER);
|
||||
let buf = BTreeMap::ser(&inner.relsizes)?;
|
||||
let buf = OrderedVec::ser(&inner.relsizes)?;
|
||||
chapter.write_all(&buf)?;
|
||||
let book = chapter.close()?;
|
||||
|
||||
@@ -532,7 +533,7 @@ impl DeltaLayer {
|
||||
let page_version_metas = BTreeMap::des(&chapter)?;
|
||||
|
||||
let chapter = book.read_chapter(REL_SIZES_CHAPTER)?;
|
||||
let relsizes = BTreeMap::des(&chapter)?;
|
||||
let relsizes = OrderedVec::des(&chapter)?;
|
||||
|
||||
debug!("loaded from {}", &path.display());
|
||||
|
||||
@@ -564,7 +565,7 @@ impl DeltaLayer {
|
||||
inner: Mutex::new(DeltaLayerInner {
|
||||
loaded: false,
|
||||
page_version_metas: BTreeMap::new(),
|
||||
relsizes: BTreeMap::new(),
|
||||
relsizes: OrderedVec::default(),
|
||||
}),
|
||||
predecessor,
|
||||
}
|
||||
@@ -588,7 +589,7 @@ impl DeltaLayer {
|
||||
inner: Mutex::new(DeltaLayerInner {
|
||||
loaded: false,
|
||||
page_version_metas: BTreeMap::new(),
|
||||
relsizes: BTreeMap::new(),
|
||||
relsizes: OrderedVec::default(),
|
||||
}),
|
||||
predecessor: None,
|
||||
})
|
||||
|
||||
@@ -8,6 +8,8 @@ pub mod lsn;
|
||||
/// SeqWait allows waiting for a future sequence number to arrive
|
||||
pub mod seqwait;
|
||||
|
||||
pub mod ordered_vec;
|
||||
|
||||
// Async version of SeqWait. Currently unused.
|
||||
// pub mod seqwait_async;
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
ops::{Bound, RangeBounds},
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct OrderedVec<K, V>(Vec<(K, V)>);
|
||||
|
||||
impl<K, V> Default for OrderedVec<K, V> {
|
||||
fn default() -> Self {
|
||||
Self(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Ord + Copy, V> OrderedVec<K, V> {
|
||||
pub fn iter(&self) -> std::slice::Iter<'_, (K, V)> {
|
||||
self.0.iter()
|
||||
}
|
||||
|
||||
pub fn range<R: RangeBounds<K>>(&self, range: R) -> &[(K, V)] {
|
||||
let start_idx = match range.start_bound() {
|
||||
Bound::Included(key) => match self.0.binary_search_by_key(key, extract_key) {
|
||||
Ok(idx) => idx,
|
||||
Err(idx) => idx,
|
||||
},
|
||||
Bound::Excluded(key) => match self.0.binary_search_by_key(key, extract_key) {
|
||||
Ok(idx) => idx + 1,
|
||||
Err(idx) => idx,
|
||||
},
|
||||
Bound::Unbounded => 0,
|
||||
};
|
||||
|
||||
let end_idx = match range.end_bound() {
|
||||
Bound::Included(key) => match self.0.binary_search_by_key(key, extract_key) {
|
||||
Ok(idx) => idx,
|
||||
Err(idx) => idx + 1,
|
||||
},
|
||||
Bound::Excluded(key) => match self.0.binary_search_by_key(key, extract_key) {
|
||||
Ok(idx) => idx + 1,
|
||||
Err(idx) => idx + 1,
|
||||
},
|
||||
Bound::Unbounded => self.0.len(),
|
||||
};
|
||||
|
||||
&self.0[start_idx..end_idx]
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Ord, V> From<BTreeMap<K, V>> for OrderedVec<K, V> {
|
||||
fn from(map: BTreeMap<K, V>) -> Self {
|
||||
let vec: Vec<(K, V)> = map.into_iter().collect();
|
||||
|
||||
// TODO probably change this
|
||||
for windows in vec.windows(2) {
|
||||
let (k1, _data1) = &windows[0];
|
||||
let (k2, _data2) = &windows[1];
|
||||
debug_assert!(k1 < k2);
|
||||
}
|
||||
|
||||
OrderedVec(vec)
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_key<K: Copy, V>(pair: &(K, V)) -> K {
|
||||
pair.0
|
||||
}
|
||||
Reference in New Issue
Block a user