From 44c5551f1647d523c5b6a291cbcad95ab889c3ab Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Sat, 17 Jan 2026 00:03:29 +0000 Subject: [PATCH] Fix nondeterministic outputs of pdl compiler Due to unordered traversal of HashMap, the generated java code is non deterministic. This is bad from the perspective of build systems, since it causes unnecessary rebuilds if the iteration order changes. This CL switches a data structure to BTreeMap to fix the non determinism --- pdl-compiler/src/backends/java/codegen/packet.rs | 8 ++++---- pdl-compiler/src/backends/java/inheritance.rs | 8 ++++---- pdl-compiler/src/backends/java/mod.rs | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/pdl-compiler/src/backends/java/codegen/packet.rs b/pdl-compiler/src/backends/java/codegen/packet.rs index 3b0bf6e..3ea5d7d 100644 --- a/pdl-compiler/src/backends/java/codegen/packet.rs +++ b/pdl-compiler/src/backends/java/codegen/packet.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use genco::{self, prelude::Java, quote, tokens::quoted, Tokens}; use heck::{self, ToLowerCamelCase, ToUpperCamelCase}; @@ -142,7 +142,7 @@ pub fn gen_packet(name: &String, def: &PacketDef, ctx: &Context) -> Tokens $(setter_defs( &def.members, "e!(Builder), - &HashMap::new(), &def.width_fields, &ctx.heirarchy)) + &BTreeMap::new(), &def.width_fields, &ctx.heirarchy)) } } } @@ -266,7 +266,7 @@ pub fn gen_abstract_packet( } protected abstract static class UnconstrainedBuilder> extends Builder { - $(setter_defs(&def.members, "e!(B), &HashMap::new(), &def.width_fields, &ctx.heirarchy)) + $(setter_defs(&def.members, "e!(B), &BTreeMap::new(), &def.width_fields, &ctx.heirarchy)) } $(for child in children.iter() { @@ -319,7 +319,7 @@ fn getter_defs(members: &[Field]) -> Tokens { fn setter_defs( members: &[Field], builder_type: &Tokens, - constraints: &HashMap, + constraints: &BTreeMap, width_fields: &HashMap, heirarchy: &ClassHeirarchy, ) -> Tokens { diff --git a/pdl-compiler/src/backends/java/inheritance.rs b/pdl-compiler/src/backends/java/inheritance.rs index 1d244f6..761a911 100644 --- a/pdl-compiler/src/backends/java/inheritance.rs +++ b/pdl-compiler/src/backends/java/inheritance.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::collections::{HashMap, HashSet}; +use std::collections::{BTreeMap, HashMap, HashSet}; use crate::backends::java::Field; @@ -27,7 +27,7 @@ pub struct InheritanceNode { pub name: String, pub parent: Option, pub children: Vec, - pub constraints: HashMap, + pub constraints: BTreeMap, pub static_field_width: usize, pub dyn_fields: HashSet, } @@ -64,7 +64,7 @@ impl ClassHeirarchy { name, parent: None, children: Vec::new(), - constraints: HashMap::new(), + constraints: BTreeMap::new(), static_field_width, dyn_fields: non_static_members, }, @@ -75,7 +75,7 @@ impl ClassHeirarchy { &mut self, parent_name: String, child_name: String, - constraints: HashMap, + constraints: BTreeMap, fields: &Vec, ) { self.0 diff --git a/pdl-compiler/src/backends/java/mod.rs b/pdl-compiler/src/backends/java/mod.rs index d54ab58..053ceef 100644 --- a/pdl-compiler/src/backends/java/mod.rs +++ b/pdl-compiler/src/backends/java/mod.rs @@ -21,6 +21,7 @@ use genco::{ use heck::{self, ToLowerCamelCase, ToUpperCamelCase}; use std::{ cmp, + collections::BTreeMap, collections::HashMap, fs::{self, OpenOptions}, iter, mem, @@ -137,7 +138,7 @@ fn generate_classes(file: &ast::File) -> (HashMap, ClassHeirarchy heirarchy.add_child( parent_name.clone(), child_name.clone(), - HashMap::new(), + BTreeMap::new(), child.fields().unwrap(), );