Replace Bruteforce search with Hashmap lookup in block_registry (#326)

* Replace Bruteforce search to Hashmap in block_registry
This commit is contained in:
PrintedScript
2024-11-23 00:25:44 +08:00
committed by GitHub
parent 120b92cfcc
commit e83e5d7df8

View File

@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::sync::LazyLock;
use serde::Deserialize;
@@ -7,15 +8,57 @@ pub static BLOCKS: LazyLock<TopLevel> = LazyLock::new(|| {
.expect("Could not parse blocks.json registry.")
});
pub static BLOCKS_BY_ID: LazyLock<HashMap<u16, Block>> = LazyLock::new(|| {
let mut map = HashMap::new();
for block in &BLOCKS.blocks {
map.insert(block.id, block.clone());
}
map
});
pub static BLOCK_ID_BY_REGISTRY_ID: LazyLock<HashMap<String, u16>> = LazyLock::new(|| {
let mut map = HashMap::new();
for block in &BLOCKS.blocks {
map.insert(block.name.clone(), block.id);
}
map
});
pub static BLOCK_ID_BY_STATE_ID: LazyLock<HashMap<u16, u16>> = LazyLock::new(|| {
let mut map = HashMap::new();
for block in &BLOCKS.blocks {
for state in &block.states {
map.insert(state.id, block.id);
}
}
map
});
pub static STATE_INDEX_BY_STATE_ID: LazyLock<HashMap<u16, u16>> = LazyLock::new(|| {
let mut map = HashMap::new();
for block in &BLOCKS.blocks {
for (index, state) in block.states.iter().enumerate() {
map.insert(state.id, index as u16);
}
}
map
});
pub static BLOCK_ID_BY_ITEM_ID: LazyLock<HashMap<u16, u16>> = LazyLock::new(|| {
let mut map = HashMap::new();
for block in &BLOCKS.blocks {
map.insert(block.item_id, block.id);
}
map
});
pub fn get_block(registry_id: &str) -> Option<&Block> {
BLOCKS
.blocks
.iter()
.find(|&block| block.name == registry_id)
let id = BLOCK_ID_BY_REGISTRY_ID.get(registry_id)?;
BLOCKS_BY_ID.get(id)
}
pub fn get_block_by_id<'a>(id: u16) -> Option<&'a Block> {
BLOCKS.blocks.iter().find(|&block| block.id == id)
BLOCKS_BY_ID.get(&id)
}
pub fn get_state_by_state_id<'a>(id: u16) -> Option<&'a State> {
@@ -23,23 +66,21 @@ pub fn get_state_by_state_id<'a>(id: u16) -> Option<&'a State> {
}
pub fn get_block_by_state_id<'a>(id: u16) -> Option<&'a Block> {
get_block_and_state_by_state_id(id).map(|(block, _)| block)
let block_id = BLOCK_ID_BY_STATE_ID.get(&id)?;
BLOCKS_BY_ID.get(block_id)
}
pub fn get_block_and_state_by_state_id<'a>(id: u16) -> Option<(&'a Block, &'a State)> {
for block in &BLOCKS.blocks {
for state in &block.states {
if state.id == id {
return Some((block, state));
}
}
}
None
let block_id = BLOCK_ID_BY_STATE_ID.get(&id)?;
let block = BLOCKS_BY_ID.get(block_id)?;
let state_index = STATE_INDEX_BY_STATE_ID.get(&id)?;
let state = block.states.get(*state_index as usize)?;
Some((block, state))
}
pub fn get_block_by_item<'a>(item_id: u16) -> Option<&'a Block> {
BLOCKS.blocks.iter().find(|&block| block.item_id == item_id)
let block_id = BLOCK_ID_BY_ITEM_ID.get(&item_id)?;
BLOCKS_BY_ID.get(block_id)
}
#[expect(dead_code)]
#[derive(Deserialize, Clone, Debug)]