mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-17 02:12:56 +00:00
make 100 layers
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use pageserver::{tenant::{disk_btree::{DiskBtreeBuilder, DiskBtreeReader, VisitDirection}, block_io::{BlockBuf, FileBlockReader}, storage_layer::DeltaLayerWriter}, repository::Key, virtual_file::{VirtualFile, self}, page_cache};
|
||||
use std::time::Instant;
|
||||
use std::{time::Instant, collections::BTreeMap};
|
||||
use rand::prelude::{SeedableRng, SliceRandom, StdRng};
|
||||
use utils::{id::{TimelineId, TenantId}, lsn::Lsn};
|
||||
use std::{io::{Read, Write}, path::PathBuf};
|
||||
@@ -13,34 +13,6 @@ struct MockLayer {
|
||||
}
|
||||
|
||||
impl MockLayer {
|
||||
fn make_simple(n_keys: i128) -> Self {
|
||||
let block_buf = BlockBuf::new();
|
||||
let mut writer = DiskBtreeBuilder::<_, 24>::new(block_buf);
|
||||
for i in 0..n_keys {
|
||||
let key: Key = Key::from_i128(i);
|
||||
let value: u64 = i as u64;
|
||||
|
||||
let mut key_bytes: [u8; 24] = [8u8; 24];
|
||||
key.write_to_byte_slice(&mut key_bytes);
|
||||
writer.append(&key_bytes, value).unwrap();
|
||||
}
|
||||
let (index_root_blk, block_buf) = writer.finish().unwrap();
|
||||
let index_start_blk = 0; // ???
|
||||
let path = std::env::current_dir().unwrap().join("btree.tmp");
|
||||
let layer = MockLayer {
|
||||
path: path.clone(),
|
||||
index_start_blk,
|
||||
index_root_blk,
|
||||
};
|
||||
|
||||
let mut file = VirtualFile::create(&path).unwrap();
|
||||
for buf in block_buf.blocks {
|
||||
file.write_all(buf.as_ref()).unwrap();
|
||||
}
|
||||
|
||||
layer
|
||||
}
|
||||
|
||||
fn read(&self, key: i128) -> Option<u64> {
|
||||
// Read from disk btree
|
||||
let file = FileBlockReader::new(VirtualFile::open(&self.path).unwrap());
|
||||
@@ -66,6 +38,47 @@ impl MockLayer {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_simple(n_keys: i128, name: &str) -> MockLayer {
|
||||
let block_buf = BlockBuf::new();
|
||||
let mut writer = DiskBtreeBuilder::<_, 24>::new(block_buf);
|
||||
for i in 0..n_keys {
|
||||
let key: Key = Key::from_i128(i);
|
||||
let value: u64 = i as u64;
|
||||
|
||||
let mut key_bytes: [u8; 24] = [8u8; 24];
|
||||
key.write_to_byte_slice(&mut key_bytes);
|
||||
writer.append(&key_bytes, value).unwrap();
|
||||
}
|
||||
let (index_root_blk, block_buf) = writer.finish().unwrap();
|
||||
let index_start_blk = 0; // ???
|
||||
let path = std::env::current_dir().unwrap()
|
||||
.parent().unwrap()
|
||||
.join("test_output")
|
||||
.join("bench_disk_lookup")
|
||||
.join("disk_btree")
|
||||
.join(name);
|
||||
std::fs::create_dir_all(path.clone().parent().unwrap()).unwrap();
|
||||
let layer = MockLayer {
|
||||
path: path.clone(),
|
||||
index_start_blk,
|
||||
index_root_blk,
|
||||
};
|
||||
|
||||
let mut file = VirtualFile::create(&path).unwrap();
|
||||
for buf in block_buf.blocks {
|
||||
file.write_all(buf.as_ref()).unwrap();
|
||||
}
|
||||
|
||||
layer
|
||||
}
|
||||
|
||||
fn make_many(n_keys: i128, n_layers: i128) -> Vec<MockLayer> {
|
||||
(0..n_layers)
|
||||
.map(|i| make_simple(n_keys, &format!("layer_{}.tmp", i)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
// cargo bench --bench bench_disk_lookup
|
||||
fn bench_disk_lookup(c: &mut Criterion) {
|
||||
virtual_file::init(10);
|
||||
@@ -74,27 +87,41 @@ fn bench_disk_lookup(c: &mut Criterion) {
|
||||
// Results in a 40MB index
|
||||
let n_keys = 4_000_000;
|
||||
|
||||
// One layer for each query
|
||||
let n_layers = 100;
|
||||
let n_queries = n_layers;
|
||||
|
||||
// Write to disk btree
|
||||
let layer = MockLayer::make_simple(n_keys);
|
||||
let layers = make_many(n_keys, n_layers);
|
||||
|
||||
// Write to mem btrees
|
||||
let mem_btrees: Vec<BTreeMap<i128, u64>> = (0..n_layers)
|
||||
.map(|_| (0..n_keys)
|
||||
.map(|i| (i as i128, i as u64))
|
||||
.collect())
|
||||
.collect();
|
||||
|
||||
// Pick queries
|
||||
let rng = &mut StdRng::seed_from_u64(1);
|
||||
let queries: Vec<_> = (0..n_keys).collect();
|
||||
let queries: Vec<_> = queries.choose_multiple(rng, 100).copied().collect();
|
||||
|
||||
let now = Instant::now();
|
||||
black_box({
|
||||
assert_eq!(layer.read(queries[0]), Some(queries[0] as u64));
|
||||
});
|
||||
println!("Finished one query in {:?}", now.elapsed());
|
||||
let queries: Vec<_> = queries.choose_multiple(rng, n_queries as usize).copied().collect();
|
||||
|
||||
// Define and name the benchmark function
|
||||
let mut group = c.benchmark_group("g1");
|
||||
group.bench_function("f1", |b| {
|
||||
group.bench_function("disk_btree", |b| {
|
||||
b.iter(|| {
|
||||
for q in queries.clone().into_iter() {
|
||||
for (i, q) in queries.clone().into_iter().enumerate() {
|
||||
black_box({
|
||||
assert_eq!(layer.read(q), Some(q as u64));
|
||||
assert_eq!(layers[i].read(q), Some(q as u64));
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
||||
group.bench_function("mem_btree", |b| {
|
||||
b.iter(|| {
|
||||
for (i, q) in queries.clone().into_iter().enumerate() {
|
||||
black_box({
|
||||
assert_eq!(mem_btrees[i].get(&q), Some(&(q as u64)));
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
@@ -80,6 +80,7 @@ use utils::{
|
||||
mod blob_io;
|
||||
pub mod block_io;
|
||||
pub mod disk_btree;
|
||||
pub mod disk_persistent_bst;
|
||||
pub(crate) mod ephemeral_file;
|
||||
pub mod layer_map;
|
||||
|
||||
|
||||
0
pageserver/src/tenant/disk_persistent_bst.rs
Normal file
0
pageserver/src/tenant/disk_persistent_bst.rs
Normal file
@@ -709,9 +709,6 @@ impl DeltaLayerWriterInner {
|
||||
// FIXME: throw an error instead?
|
||||
let path = DeltaLayer::temp_path_for(conf, timeline_id, tenant_id, key_start, &lsn_range);
|
||||
|
||||
// HACK
|
||||
fs::create_dir_all(path.clone().parent().unwrap())?;
|
||||
|
||||
let mut file = VirtualFile::create(&path)?;
|
||||
// make room for the header block
|
||||
file.seek(SeekFrom::Start(PAGE_SZ as u64))?;
|
||||
|
||||
Reference in New Issue
Block a user