mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 18:24:05 +02:00
optimize prop flattening cycle prevention
This commit is contained in:
parent
a7a46384ce
commit
836e7718ce
1 changed files with 40 additions and 38 deletions
|
|
@ -319,11 +319,11 @@ fn test_parse_send_table_roundtrip() {
|
||||||
impl ParseSendTable {
|
impl ParseSendTable {
|
||||||
pub fn flatten_props(&self, tables: &[ParseSendTable]) -> Result<Vec<SendPropDefinition>> {
|
pub fn flatten_props(&self, tables: &[ParseSendTable]) -> Result<Vec<SendPropDefinition>> {
|
||||||
let mut flat = Vec::with_capacity(32);
|
let mut flat = Vec::with_capacity(32);
|
||||||
self.get_all_props(
|
self.push_props_end(
|
||||||
tables,
|
tables,
|
||||||
&self.get_excludes(tables, &mut Vec::with_capacity(8)),
|
&self.get_excludes(tables),
|
||||||
&mut flat,
|
&mut flat,
|
||||||
Vec::with_capacity(8),
|
&mut Vec::with_capacity(16),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// sort often changed props before the others
|
// sort often changed props before the others
|
||||||
|
|
@ -340,13 +340,21 @@ impl ParseSendTable {
|
||||||
Ok(flat)
|
Ok(flat)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_excludes<'a>(
|
fn get_excludes<'a>(&'a self, tables: &'a [ParseSendTable]) -> Vec<SendPropIdentifier> {
|
||||||
|
let mut excludes = Vec::with_capacity(8);
|
||||||
|
|
||||||
|
self.build_excludes(tables, &mut Vec::with_capacity(8), &mut excludes);
|
||||||
|
|
||||||
|
excludes
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_excludes<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
tables: &'a [ParseSendTable],
|
tables: &'a [ParseSendTable],
|
||||||
processed_tables: &mut Vec<SendTableName>,
|
processed_tables: &mut Vec<&'a SendTableName>,
|
||||||
) -> Vec<SendPropIdentifier> {
|
excludes: &mut Vec<SendPropIdentifier>,
|
||||||
processed_tables.push(self.name.clone());
|
) {
|
||||||
let mut excludes = Vec::with_capacity(8);
|
processed_tables.push(&self.name);
|
||||||
|
|
||||||
for prop in self.props.iter() {
|
for prop in self.props.iter() {
|
||||||
if let Some(exclude_table) = prop.get_exclude_table() {
|
if let Some(exclude_table) = prop.get_exclude_table() {
|
||||||
|
|
@ -355,73 +363,67 @@ impl ParseSendTable {
|
||||||
prop.name.as_str(),
|
prop.name.as_str(),
|
||||||
))
|
))
|
||||||
} else if let Some(table) = prop.get_data_table(tables) {
|
} else if let Some(table) = prop.get_data_table(tables) {
|
||||||
if !processed_tables.contains(&table.name) {
|
if !processed_tables.contains(&&table.name) {
|
||||||
excludes.extend_from_slice(&table.get_excludes(tables, processed_tables));
|
table.build_excludes(tables, processed_tables, excludes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
excludes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: below is a direct port from the js which is a direct port from C++ and not very optimal
|
// TODO: below is a direct port from the js which is a direct port from C++ and not very optimal
|
||||||
fn get_all_props(
|
fn push_props_end<'a>(
|
||||||
&self,
|
&'a self,
|
||||||
tables: &[ParseSendTable],
|
tables: &'a [ParseSendTable],
|
||||||
excludes: &[SendPropIdentifier],
|
excludes: &[SendPropIdentifier],
|
||||||
props: &mut Vec<SendPropDefinition>,
|
props: &mut Vec<SendPropDefinition>,
|
||||||
processed_tables: Vec<SendTableName>,
|
table_stack: &mut Vec<&'a SendTableName>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut local_props = Vec::new();
|
let mut local_props = Vec::new();
|
||||||
|
|
||||||
self.get_all_props_iterator_props(
|
self.push_props_collapse(tables, excludes, &mut local_props, props, table_stack)?;
|
||||||
tables,
|
|
||||||
excludes,
|
|
||||||
&mut local_props,
|
|
||||||
props,
|
|
||||||
processed_tables,
|
|
||||||
)?;
|
|
||||||
props.extend_from_slice(&local_props);
|
props.extend_from_slice(&local_props);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_all_props_iterator_props(
|
fn push_props_collapse<'a>(
|
||||||
&self,
|
&'a self,
|
||||||
tables: &[ParseSendTable],
|
tables: &'a [ParseSendTable],
|
||||||
excludes: &[SendPropIdentifier],
|
excludes: &[SendPropIdentifier],
|
||||||
local_props: &mut Vec<SendPropDefinition>,
|
local_props: &mut Vec<SendPropDefinition>,
|
||||||
props: &mut Vec<SendPropDefinition>,
|
props: &mut Vec<SendPropDefinition>,
|
||||||
processed_tables: Vec<SendTableName>,
|
table_stack: &mut Vec<&'a SendTableName>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let processed_tables = &processed_tables;
|
table_stack.push(&self.name);
|
||||||
self.props
|
|
||||||
|
let result = self
|
||||||
|
.props
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|prop| !prop.is_exclude())
|
.filter(|prop| !prop.is_exclude())
|
||||||
.filter(|prop| !excludes.iter().any(|exclude| *exclude == prop.identifier()))
|
.filter(|prop| !excludes.iter().any(|exclude| *exclude == prop.identifier()))
|
||||||
.try_for_each(|prop| {
|
.try_for_each(|prop| {
|
||||||
let mut child_processed_tables = processed_tables.clone();
|
|
||||||
child_processed_tables.push(self.name.clone());
|
|
||||||
if let Some(table) = prop.get_data_table(tables) {
|
if let Some(table) = prop.get_data_table(tables) {
|
||||||
if !processed_tables.contains(&table.name) {
|
if !table_stack.contains(&&table.name) {
|
||||||
if prop.flags.contains(SendPropFlag::Collapsible) {
|
if prop.flags.contains(SendPropFlag::Collapsible) {
|
||||||
table.get_all_props_iterator_props(
|
table.push_props_collapse(
|
||||||
tables,
|
tables,
|
||||||
excludes,
|
excludes,
|
||||||
local_props,
|
local_props,
|
||||||
props,
|
props,
|
||||||
child_processed_tables,
|
table_stack,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
table.get_all_props(tables, excludes, props, child_processed_tables)?;
|
table.push_props_end(tables, excludes, props, table_stack)?;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
dbg!(table.name.as_str());
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
local_props.push(SendPropDefinition::try_from(prop)?);
|
local_props.push(SendPropDefinition::try_from(prop)?);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
});
|
||||||
|
|
||||||
|
table_stack.pop();
|
||||||
|
|
||||||
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue