diff --git a/azalea-client/src/test_simulation.rs b/azalea-client/src/test_simulation.rs index b9e9b8ec..67dcb818 100644 --- a/azalea-client/src/test_simulation.rs +++ b/azalea-client/src/test_simulation.rs @@ -264,7 +264,7 @@ pub fn make_basic_empty_chunk( z: pos.z, chunk_data: ClientboundLevelChunkPacketData { heightmaps: Nbt::None, - data: chunk_bytes.into(), + data: Arc::new(chunk_bytes.into()), block_entities: vec![], }, light_data: ClientboundLightUpdatePacketData::default(), diff --git a/azalea-language/src/lib.rs b/azalea-language/src/lib.rs index bb5d144e..d86a2697 100755 --- a/azalea-language/src/lib.rs +++ b/azalea-language/src/lib.rs @@ -4,9 +4,22 @@ use std::{collections::HashMap, sync::LazyLock}; use compact_str::CompactString; -pub static STORAGE: LazyLock> = - LazyLock::new(|| serde_json::from_str(include_str!("en_us.json")).unwrap()); +pub static STORAGE: LazyLock> = LazyLock::new(|| { + let json = + serde_json::from_str::>(include_str!("en_us.json")) + .unwrap(); + let mut json = json.into_iter().collect::>(); + + // sort by key to make binary search work + json.sort_by(|a, b| a.0.cmp(&b.0)); + + json +}); pub fn get(key: &str) -> Option<&str> { - STORAGE.get(key).map(|s| s.as_str()) + let key = CompactString::from(key); + let storage = &*STORAGE; + // more memory efficient than a hashmap lookup + let index = storage.binary_search_by(|(k, _)| k.cmp(&key)); + index.ok().map(|i| storage[i].1.as_str()) } diff --git a/azalea-protocol/src/packets/game/c_level_chunk_with_light.rs b/azalea-protocol/src/packets/game/c_level_chunk_with_light.rs index 43237c3b..c27c24a9 100755 --- a/azalea-protocol/src/packets/game/c_level_chunk_with_light.rs +++ b/azalea-protocol/src/packets/game/c_level_chunk_with_light.rs @@ -25,7 +25,7 @@ pub struct ClientboundLevelChunkPacketData { /// /// This is an Arc because it's often very big and we want it to be cheap to /// clone. - pub data: Arc>, + pub data: Arc>, pub block_entities: Vec, } diff --git a/azalea-world/src/bit_storage.rs b/azalea-world/src/bit_storage.rs index 1b0c1a56..7d1b72e1 100755 --- a/azalea-world/src/bit_storage.rs +++ b/azalea-world/src/bit_storage.rs @@ -101,7 +101,11 @@ impl Error for BitStorageError {} impl BitStorage { /// Create a new BitStorage with the given number of bits per entry. /// `size` is the number of entries in the BitStorage. - pub fn new(bits: usize, size: usize, data: Option>) -> Result { + pub fn new( + bits: usize, + size: usize, + data: Option>, + ) -> Result { if let Some(data) = &data { // 0 bit storage if data.is_empty() { @@ -132,11 +136,11 @@ impl BitStorage { } data } else { - vec![0; calculated_length] + vec![0; calculated_length].into() }; Ok(BitStorage { - data: using_data.into(), + data: using_data, bits, mask, size, @@ -252,7 +256,7 @@ mod tests { 1, 2, 2, 3, 4, 4, 5, 6, 6, 4, 8, 0, 7, 4, 3, 13, 15, 16, 9, 14, 10, 12, 0, 2, ]; let compact_data: [u64; 2] = [0x0020863148418841, 0x01018A7260F68C87]; - let storage = BitStorage::new(5, data.len(), Some(compact_data.to_vec())).unwrap(); + let storage = BitStorage::new(5, data.len(), Some(Box::new(compact_data))).unwrap(); for (i, expected) in data.iter().enumerate() { assert_eq!(storage.get(i), *expected); diff --git a/azalea-world/src/chunk_storage.rs b/azalea-world/src/chunk_storage.rs index 9592abbf..db5ac877 100755 --- a/azalea-world/src/chunk_storage.rs +++ b/azalea-world/src/chunk_storage.rs @@ -353,7 +353,7 @@ impl Chunk { warn!("Heightmap {name} is not a long array"); continue; }; - let data: Vec = data.iter().map(|x| *x as u64).collect(); + let data: Box<[u64]> = data.iter().map(|x| *x as u64).collect(); let heightmap = Heightmap::new(kind, dimension_height, min_y, data); heightmaps.insert(kind, heightmap); } diff --git a/azalea-world/src/heightmap.rs b/azalea-world/src/heightmap.rs index 35142cf2..f1ef30d2 100644 --- a/azalea-world/src/heightmap.rs +++ b/azalea-world/src/heightmap.rs @@ -56,7 +56,7 @@ impl HeightmapKind { } impl Heightmap { - pub fn new(kind: HeightmapKind, dimension_height: u32, min_y: i32, data: Vec) -> Self { + pub fn new(kind: HeightmapKind, dimension_height: u32, min_y: i32, data: Box<[u64]>) -> Self { let bits = math::ceil_log2(dimension_height + 1); let data = BitStorage::new(bits as usize, 16 * 16, Some(data)).unwrap(); Self { kind, data, min_y } diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index dd5f7daa..97786e7c 100755 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -31,7 +31,7 @@ impl PalettedContainer { pub fn new(container_type: PalettedContainerKind) -> Self { let palette = Palette::SingleValue(0); let size = container_type.size(); - let storage = BitStorage::new(0, size, Some(vec![])).unwrap(); + let storage = BitStorage::new(0, size, Some(Box::new([]))).unwrap(); PalettedContainer { bits_per_entry: 0, @@ -76,7 +76,7 @@ impl PalettedContainer { bits_per_entry.into(), size, if data.is_empty() { - Some(vec![]) + Some(Box::new([])) } else { // we're going to update the data after creating the bitstorage None