change: Added benchmarks and started on the on-disk storage
This commit is contained in:
		
							
								
								
									
										38
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										38
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -1003,6 +1003,12 @@ version = "0.3.27"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
 | 
					checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "ppv-lite86"
 | 
				
			||||||
 | 
					version = "0.2.17"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "proc-macro-hack"
 | 
					name = "proc-macro-hack"
 | 
				
			||||||
version = "0.5.20+deprecated"
 | 
					version = "0.5.20+deprecated"
 | 
				
			||||||
@@ -1027,6 +1033,36 @@ dependencies = [
 | 
				
			|||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rand"
 | 
				
			||||||
 | 
					version = "0.8.5"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "rand_chacha",
 | 
				
			||||||
 | 
					 "rand_core",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rand_chacha"
 | 
				
			||||||
 | 
					version = "0.3.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "ppv-lite86",
 | 
				
			||||||
 | 
					 "rand_core",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rand_core"
 | 
				
			||||||
 | 
					version = "0.6.4"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "getrandom",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "rustc-demangle"
 | 
					name = "rustc-demangle"
 | 
				
			||||||
version = "0.1.23"
 | 
					version = "0.1.23"
 | 
				
			||||||
@@ -1149,9 +1185,11 @@ dependencies = [
 | 
				
			|||||||
name = "spatial-db"
 | 
					name = "spatial-db"
 | 
				
			||||||
version = "0.1.0"
 | 
					version = "0.1.0"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "arrow-array",
 | 
				
			||||||
 "axum",
 | 
					 "axum",
 | 
				
			||||||
 "clap",
 | 
					 "clap",
 | 
				
			||||||
 "parquet",
 | 
					 "parquet",
 | 
				
			||||||
 | 
					 "rand",
 | 
				
			||||||
 "tokio",
 | 
					 "tokio",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,9 @@ edition = "2021"
 | 
				
			|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
					# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
 | 
					arrow-array = "47.0.0"
 | 
				
			||||||
axum = "0.6.20"
 | 
					axum = "0.6.20"
 | 
				
			||||||
clap = { version = "4.4.5", features = ["derive"] }
 | 
					clap = { version = "4.4.5", features = ["derive"] }
 | 
				
			||||||
parquet = "47.0.0"
 | 
					parquet = "47.0.0"
 | 
				
			||||||
 | 
					rand = "0.8.5"
 | 
				
			||||||
tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] }
 | 
					tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					#![feature(test)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod simple_server;
 | 
					mod simple_server;
 | 
				
			||||||
mod storage;
 | 
					mod storage;
 | 
				
			||||||
mod storage_server;
 | 
					mod storage_server;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,6 @@
 | 
				
			|||||||
use crate::storage::world::{BlockID, BlockPos, BlockRange, ChunkData, ChunkPos};
 | 
					use crate::storage::world::{BlockID, BlockPos, BlockRange, ChunkData, ChunkPos};
 | 
				
			||||||
use crate::storage_server::StorageServer;
 | 
					use crate::storage_server::StorageServer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					 | 
				
			||||||
struct SingleBlock {
 | 
					 | 
				
			||||||
    id: BlockID,
 | 
					 | 
				
			||||||
    position: BlockPos,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
struct MultipleBlocks {
 | 
					struct MultipleBlocks {
 | 
				
			||||||
    id: BlockID,
 | 
					    id: BlockID,
 | 
				
			||||||
@@ -76,10 +70,8 @@ impl StorageServer for SimpleServer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        let chunk = chunk.expect("Could not find chunk");
 | 
					        let chunk = chunk.expect("Could not find chunk");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        println!("Chunk for {:?} is at {:?}", world_position, chunk.pos);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Find the section that the block is located in
 | 
					        // Find the section that the block is located in
 | 
				
			||||||
        let current_section = &mut chunk.sections[world_position.y / 16];
 | 
					        let current_section = &mut chunk.sections[world_position.y % 16];
 | 
				
			||||||
        // Find the index that the block is at, and update its state
 | 
					        // Find the index that the block is at, and update its state
 | 
				
			||||||
        let chunk_array_index = current_section.index_of_block(&world_position);
 | 
					        let chunk_array_index = current_section.index_of_block(&world_position);
 | 
				
			||||||
        current_section.update_block_at_index(&target_state, chunk_array_index);
 | 
					        current_section.update_block_at_index(&target_state, chunk_array_index);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								src/storage/disk_storage.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/storage/disk_storage.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					use super::world::{BlockID, ChunkData, ChunkPos};
 | 
				
			||||||
 | 
					use std::fs::File;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const DATABASE_FILE_LOCATION: &str = "./persistence";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct RunLengthEncoding {
 | 
				
			||||||
 | 
					    pairs: Vec<(usize, BlockID)>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl RunLengthEncoding {
 | 
				
			||||||
 | 
					    fn from_chunk(chunk_data: &ChunkData) -> Self {
 | 
				
			||||||
 | 
					        for section in chunk_data.sections {
 | 
				
			||||||
 | 
					            for index in section.chunk_data {
 | 
				
			||||||
 | 
					                // Yes
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1,2 +1,2 @@
 | 
				
			|||||||
 | 
					// mod disk_storage;
 | 
				
			||||||
pub mod world;
 | 
					pub mod world;
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,8 +16,8 @@ pub struct ChunkPos {
 | 
				
			|||||||
impl From<&BlockPos> for ChunkPos {
 | 
					impl From<&BlockPos> for ChunkPos {
 | 
				
			||||||
    fn from(value: &BlockPos) -> Self {
 | 
					    fn from(value: &BlockPos) -> Self {
 | 
				
			||||||
        ChunkPos {
 | 
					        ChunkPos {
 | 
				
			||||||
            x: value.x.rem_euclid(16),
 | 
					            x: value.x / 16,
 | 
				
			||||||
            z: value.z.rem_euclid(16),
 | 
					            z: value.z / 16,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,2 +1,2 @@
 | 
				
			|||||||
mod insert_one;
 | 
					mod insert_one;
 | 
				
			||||||
 | 
					mod performance_testing;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										154
									
								
								src/tests/performance_testing.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								src/tests/performance_testing.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
				
			|||||||
 | 
					extern crate test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					mod tests {
 | 
				
			||||||
 | 
					    use super::*;
 | 
				
			||||||
 | 
					    use crate::{
 | 
				
			||||||
 | 
					        simple_server::server::SimpleServer,
 | 
				
			||||||
 | 
					        storage::world::{BlockID, BlockPos},
 | 
				
			||||||
 | 
					        storage_server::StorageServer,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    use rand::prelude::*;
 | 
				
			||||||
 | 
					    use test::Bencher;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[bench]
 | 
				
			||||||
 | 
					    fn bench_add_sequential_elements(b: &mut Bencher) {
 | 
				
			||||||
 | 
					        let mut server = SimpleServer::new();
 | 
				
			||||||
 | 
					        let mut x = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b.iter(|| {
 | 
				
			||||||
 | 
					            server.change_block(BlockID::Generic, &BlockPos::new(x, 0, 0));
 | 
				
			||||||
 | 
					            x += 1;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[bench]
 | 
				
			||||||
 | 
					    fn bench_add_clustered_points(b: &mut Bencher) {
 | 
				
			||||||
 | 
					        let mut server = SimpleServer::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut rng = rand::thread_rng();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static MAX_RANGE: isize = 128;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b.iter(|| {
 | 
				
			||||||
 | 
					            let x: isize = rng.gen_range(-MAX_RANGE..MAX_RANGE);
 | 
				
			||||||
 | 
					            let y: usize = rng.gen::<u8>() as usize;
 | 
				
			||||||
 | 
					            let z: isize = rng.gen_range(-MAX_RANGE..MAX_RANGE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            server.change_block(BlockID::Generic, &BlockPos::new(x, y, z));
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[bench]
 | 
				
			||||||
 | 
					    fn bench_add_spread_out_points(b: &mut Bencher) {
 | 
				
			||||||
 | 
					        let mut server = SimpleServer::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut rng = rand::thread_rng();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static MAX_RANGE: isize = 65536;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b.iter(|| {
 | 
				
			||||||
 | 
					            let x: isize = rng.gen_range(-MAX_RANGE..MAX_RANGE);
 | 
				
			||||||
 | 
					            let y: usize = rng.gen::<u8>() as usize;
 | 
				
			||||||
 | 
					            let z: isize = rng.gen_range(-MAX_RANGE..MAX_RANGE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            server.change_block(BlockID::Generic, &BlockPos::new(x, y, z));
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[bench]
 | 
				
			||||||
 | 
					    fn bench_insert_and_read_clustered(b: &mut Bencher) {
 | 
				
			||||||
 | 
					        let mut server = SimpleServer::new();
 | 
				
			||||||
 | 
					        let mut rng = rand::thread_rng();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static NUM_BLOCKS: usize = 1_000;
 | 
				
			||||||
 | 
					        static MAX_RANGE: isize = 128;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut positions = Vec::with_capacity(NUM_BLOCKS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for _ in 0..NUM_BLOCKS {
 | 
				
			||||||
 | 
					            let x: isize = rng.gen_range(-MAX_RANGE..MAX_RANGE);
 | 
				
			||||||
 | 
					            let y: usize = rng.gen::<u8>() as usize;
 | 
				
			||||||
 | 
					            let z: isize = rng.gen_range(-MAX_RANGE..MAX_RANGE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let pos = BlockPos::new(x, y, z);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            server.change_block(BlockID::Generic, &BlockPos::new(x, y, z));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            positions.push(pos);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b.iter(|| {
 | 
				
			||||||
 | 
					            for i in 0..NUM_BLOCKS {
 | 
				
			||||||
 | 
					                assert_eq!(server.read_block_at(&positions[i]), BlockID::Generic);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[bench]
 | 
				
			||||||
 | 
					    fn bench_insert_and_read_cache(b: &mut Bencher) {
 | 
				
			||||||
 | 
					        let mut server = SimpleServer::new();
 | 
				
			||||||
 | 
					        let mut rng = rand::thread_rng();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static NUM_BLOCKS: usize = 1_000;
 | 
				
			||||||
 | 
					        static MAX_RANGE: isize = 128;
 | 
				
			||||||
 | 
					        static EXPANDED_RANGE: isize = 2048;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut positions = Vec::with_capacity(NUM_BLOCKS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for _ in 0..NUM_BLOCKS {
 | 
				
			||||||
 | 
					            let x: isize = rng.gen_range(-MAX_RANGE..MAX_RANGE);
 | 
				
			||||||
 | 
					            let y: usize = rng.gen::<u8>() as usize;
 | 
				
			||||||
 | 
					            let z: isize = rng.gen_range(-MAX_RANGE..MAX_RANGE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let pos = BlockPos::new(x, y, z);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            server.change_block(BlockID::Generic, &BlockPos::new(x, y, z));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            positions.push(pos);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b.iter(|| {
 | 
				
			||||||
 | 
					            // Read blocks that are already in the server
 | 
				
			||||||
 | 
					            for i in 0..NUM_BLOCKS {
 | 
				
			||||||
 | 
					                assert_eq!(server.read_block_at(&positions[i]), BlockID::Generic);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Read blocks that might not be in the server, triggering a miss
 | 
				
			||||||
 | 
					            for _ in 0..NUM_BLOCKS {
 | 
				
			||||||
 | 
					                let x: isize = rng.gen_range(-EXPANDED_RANGE..EXPANDED_RANGE);
 | 
				
			||||||
 | 
					                let y: usize = rng.gen::<u8>() as usize;
 | 
				
			||||||
 | 
					                let z: isize = rng.gen_range(-EXPANDED_RANGE..EXPANDED_RANGE);
 | 
				
			||||||
 | 
					                server.read_block_at(&BlockPos::new(x, y, z));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[bench]
 | 
				
			||||||
 | 
					    fn bench_clustered_many_misses(b: &mut Bencher) {
 | 
				
			||||||
 | 
					        let mut server = SimpleServer::new();
 | 
				
			||||||
 | 
					        let mut rng = rand::thread_rng();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static NUM_BLOCKS: usize = 1_000;
 | 
				
			||||||
 | 
					        static MAX_RANGE: isize = 128;
 | 
				
			||||||
 | 
					        static EXPANDED_RANGE: isize = 2048;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for _ in 0..NUM_BLOCKS {
 | 
				
			||||||
 | 
					            let x: isize = rng.gen_range(-MAX_RANGE..MAX_RANGE);
 | 
				
			||||||
 | 
					            let y: usize = rng.gen::<u8>() as usize;
 | 
				
			||||||
 | 
					            let z: isize = rng.gen_range(-MAX_RANGE..MAX_RANGE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            server.change_block(BlockID::Generic, &BlockPos::new(x, y, z));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        b.iter(|| {
 | 
				
			||||||
 | 
					            // Read blocks that might not be in the server, triggering a miss
 | 
				
			||||||
 | 
					            for _ in 0..NUM_BLOCKS {
 | 
				
			||||||
 | 
					                let x: isize = rng.gen_range(-EXPANDED_RANGE..EXPANDED_RANGE);
 | 
				
			||||||
 | 
					                let y: usize = rng.gen::<u8>() as usize;
 | 
				
			||||||
 | 
					                let z: isize = rng.gen_range(-EXPANDED_RANGE..EXPANDED_RANGE);
 | 
				
			||||||
 | 
					                server.read_block_at(&BlockPos::new(x, y, z));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user