Skip to content

Commit

Permalink
perf: Switched to Vec instead of HashMap in compounds
Browse files Browse the repository at this point in the history
  • Loading branch information
Norbiros committed Oct 12, 2024
1 parent 0ca901a commit f5be9cf
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 42 deletions.
7 changes: 3 additions & 4 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,9 @@ macro_rules! nbt {
macro_rules! nbt_inner {
({ $($key:tt : $value:tt),* $(,)? }) => {
$crate::NbtCompound::from_iter({
#[allow(unused_mut)]
let mut map = ::std::collections::HashMap::<::std::string::String, $crate::NbtTag>::new();
$(map.insert($key.into(), nbt_inner!(@value $value));)*
map
let mut tags = ::std::vec::Vec::<(::std::string::String, $crate::NbtTag)>::new();
$(tags.push(($key.into(), nbt_inner!(@value $value)));)*
tags
})
};
(@value $ident:ident) => { $crate::NbtTag::from($ident) };
Expand Down
72 changes: 36 additions & 36 deletions src/nbt/compound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ use bytes::{Buf, BufMut, Bytes, BytesMut};
use crab_nbt::nbt::tag::NbtTag;
use crab_nbt::nbt::utils::{get_nbt_string, END_ID};
use derive_more::Into;
use std::collections::{hash_map::IntoIter, HashMap};
use std::io::{Cursor, Write};
use std::vec::IntoIter;

#[derive(Clone, PartialEq, Debug, Default, Into)]
pub struct NbtCompound {
pub child_tags: HashMap<String, NbtTag>,
pub child_tags: Vec<(String, NbtTag)>,
}

impl NbtCompound {
pub fn new() -> NbtCompound {
NbtCompound {
child_tags: HashMap::new(),
child_tags: Vec::new(),
}
}

pub fn deserialize_content(bytes: &mut impl Buf) -> Result<NbtCompound, Error> {
let mut child_tags = HashMap::new();
let mut compound = NbtCompound::new();

while bytes.has_remaining() {
let tag_id = bytes.get_u8();
Expand All @@ -30,13 +30,13 @@ impl NbtCompound {
let name = get_nbt_string(bytes)?;

if let Ok(tag) = NbtTag::deserialize_data(bytes, tag_id) {
child_tags.insert(name, tag);
compound.put(name, tag);
} else {
break;
}
}

Ok(NbtCompound { child_tags })
Ok(compound)
}

pub fn deserialize_content_from_cursor(
Expand All @@ -62,69 +62,67 @@ impl NbtCompound {
}

pub fn put(&mut self, name: String, value: impl Into<NbtTag>) {
self.child_tags.insert(name, value.into());
if !self.child_tags.iter().any(|(key, _)| key == &name) {
self.child_tags.push((name, value.into()));
}
}

pub fn get_byte(&self, name: &str) -> Option<i8> {
self.child_tags.get(name).and_then(|tag| tag.extract_byte())
self.get(name).and_then(|tag| tag.extract_byte())
}

#[inline]
pub fn get(&self, name: &str) -> Option<&NbtTag> {
for (key, value) in &self.child_tags {
if key.as_str() == name {
return Some(value);
}
}
None
}

pub fn get_short(&self, name: &str) -> Option<i16> {
self.child_tags
.get(name)
.and_then(|tag| tag.extract_short())
self.get(name).and_then(|tag| tag.extract_short())
}

pub fn get_int(&self, name: &str) -> Option<i32> {
self.child_tags.get(name).and_then(|tag| tag.extract_int())
self.get(name).and_then(|tag| tag.extract_int())
}

pub fn get_long(&self, name: &str) -> Option<i64> {
self.child_tags.get(name).and_then(|tag| tag.extract_long())
self.get(name).and_then(|tag| tag.extract_long())
}

pub fn get_float(&self, name: &str) -> Option<f32> {
self.child_tags
.get(name)
.and_then(|tag| tag.extract_float())
self.get(name).and_then(|tag| tag.extract_float())
}

pub fn get_double(&self, name: &str) -> Option<f64> {
self.child_tags
.get(name)
.and_then(|tag| tag.extract_double())
self.get(name).and_then(|tag| tag.extract_double())
}

pub fn get_bool(&self, name: &str) -> Option<bool> {
self.child_tags.get(name).and_then(|tag| tag.extract_bool())
self.get(name).and_then(|tag| tag.extract_bool())
}

pub fn get_string(&self, name: &str) -> Option<&String> {
self.child_tags
.get(name)
.and_then(|tag| tag.extract_string())
self.get(name).and_then(|tag| tag.extract_string())
}

pub fn get_list(&self, name: &str) -> Option<&Vec<NbtTag>> {
self.child_tags.get(name).and_then(|tag| tag.extract_list())
self.get(name).and_then(|tag| tag.extract_list())
}

pub fn get_compound(&self, name: &str) -> Option<&NbtCompound> {
self.child_tags
.get(name)
.and_then(|tag| tag.extract_compound())
self.get(name).and_then(|tag| tag.extract_compound())
}

pub fn get_int_array(&self, name: &str) -> Option<&Vec<i32>> {
self.child_tags
.get(name)
.and_then(|tag| tag.extract_int_array())
self.get(name).and_then(|tag| tag.extract_int_array())
}

pub fn get_long_array(&self, name: &str) -> Option<&Vec<i64>> {
self.child_tags
.get(name)
.and_then(|tag| tag.extract_long_array())
self.get(name).and_then(|tag| tag.extract_long_array())
}
}

Expand All @@ -136,15 +134,17 @@ impl From<Nbt> for NbtCompound {

impl FromIterator<(String, NbtTag)> for NbtCompound {
fn from_iter<T: IntoIterator<Item = (String, NbtTag)>>(iter: T) -> Self {
Self {
child_tags: HashMap::from_iter(iter),
let mut compound = NbtCompound::new();
for (key, value) in iter {
compound.put(key, value);
}
compound
}
}

impl IntoIterator for NbtCompound {
type Item = (String, NbtTag);
type IntoIter = IntoIter<String, NbtTag>;
type IntoIter = IntoIter<(String, NbtTag)>;

fn into_iter(self) -> Self::IntoIter {
self.child_tags.into_iter()
Expand Down
4 changes: 2 additions & 2 deletions src/serde/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ where
pub fn to_writer_unnamed<T, W>(value: &T, mut writer: W) -> Result<()>
where
T: Serialize,
W: Write
W: Write,
{
writer.write_all(&to_bytes_unnamed(value)?)?;
Ok(())
Expand All @@ -91,7 +91,7 @@ where
pub fn to_writer<T, W>(value: &T, name: String, mut writer: W) -> Result<()>
where
T: Serialize,
W: Write
W: Write,
{
writer.write_all(&to_bytes(value, name)?)?;
Ok(())
Expand Down

0 comments on commit f5be9cf

Please sign in to comment.