Skip to content

Commit

Permalink
Preallocate property tables during deserialization (#464)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethloeffler authored Oct 29, 2024
1 parent 69f3acc commit e909f45
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 2 deletions.
13 changes: 12 additions & 1 deletion rbx_binary/src/deserializer/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,13 +295,24 @@ impl<'db, R: Read> DeserializerState<'db, R> {
let mut referents = vec![0; number_instances as usize];
chunk.read_referent_array(&mut referents)?;

let prop_capacity = self
.deserializer
.database
.classes
.get(type_name.as_str())
.map(|class| class.default_properties.len())
.unwrap_or(0);

// TODO: Check object_format and check for service markers if it's 1?

for &referent in &referents {
self.instances_by_ref.insert(
referent,
Instance {
builder: InstanceBuilder::new(&type_name),
builder: InstanceBuilder::with_property_capacity(
type_name.as_str(),
prop_capacity,
),
children: Vec::new(),
},
);
Expand Down
3 changes: 3 additions & 0 deletions rbx_dom_weak/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ where
### Other changes
* Added `UstrMapExt`, a helper trait providing convenience methods `UstrMap::new` and `UstrMap::with_capacity`.
* Added re-exports for `ustr` (a convenience function for creating `Ustr`s), `Ustr`, `UstrMap`, and `UstrSet`.
* Added `InstanceBuilder::with_property_capacity`, which can preallocate an `InstanceBuilder`'s property table. [#464]

[#464]: https://github.com/rojo-rbx/rbx-dom/pull/464

## 2.9.0 (2024-08-22)
* Added `WeakDom::descendants` and `WeakDom::descendants_of` to support iterating through the descendants of a DOM. ([#431])
Expand Down
15 changes: 15 additions & 0 deletions rbx_dom_weak/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ impl InstanceBuilder {
}
}

/// Create a new `InstanceBuilder` with the given ClassName and with a
/// property table with at least enough space for the given capacity.
pub fn with_property_capacity<S: Into<Ustr>>(class: S, capacity: usize) -> Self {
let class = class.into();
let name = class.to_string();

InstanceBuilder {
referent: Ref::new(),
name,
class,
properties: UstrMap::with_capacity(capacity),
children: Vec::new(),
}
}

/// Create a new `InstanceBuilder` with all values set to empty.
pub fn empty() -> Self {
InstanceBuilder {
Expand Down
10 changes: 9 additions & 1 deletion rbx_xml/src/deserializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,15 @@ fn deserialize_instance<R: Read>(

trace!("Class {} with referent {:?}", class_name, referent);

let builder = InstanceBuilder::new(class_name);
let prop_capacity = state
.options
.database
.classes
.get(class_name.as_str())
.map(|class| class.default_properties.len())
.unwrap_or(0);

let builder = InstanceBuilder::with_property_capacity(class_name, prop_capacity);
let instance_id = state.tree.insert(parent_id, builder);

if let Some(referent) = referent {
Expand Down

0 comments on commit e909f45

Please sign in to comment.