Skip to content

Fix hashing not being based on all attributes of Table#4079

Merged
Keavon merged 2 commits intomasterfrom
fix-table-attribute-hashing
Apr 29, 2026
Merged

Fix hashing not being based on all attributes of Table#4079
Keavon merged 2 commits intomasterfrom
fix-table-attribute-hashing

Conversation

@Keavon
Copy link
Copy Markdown
Member

@Keavon Keavon commented Apr 29, 2026

Partly closes #3779.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request integrates the CacheHash trait into the table and attribute column system, enabling hashing for type-erased attribute data. The changes include adding CacheHash bounds to various generic methods and implementing a DynHasher to facilitate object-safe hashing. Feedback focuses on improving the robustness of the hashing logic by including collection lengths to prevent collisions and ensuring the CacheHash implementation for Table remains consistent with its PartialEq contract by excluding non-serialized attributes.

Comment on lines +270 to +275
fn cache_hash_dyn(&self, state: &mut dyn core::hash::Hasher) {
let mut wrapped = DynHasher(state);
for value in &self.0 {
value.cache_hash(&mut wrapped);
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The manual iteration over the column values to hash them individually misses the opportunity to hash the column's length, which is important for distinguishing between different length columns (e.g., when one is a prefix of another). Since Vec<T> implements CacheHash (which includes the length), you can simplify this implementation by delegating directly to the inner vector.

	fn cache_hash_dyn(&self, state: &mut dyn core::hash::Hasher) {
		self.0.cache_hash(&mut DynHasher(state));
	}

Comment on lines 866 to 875
fn cache_hash<H: core::hash::Hasher>(&self, state: &mut H) {
for element in self.iter_element_values() {
element.cache_hash(state);
}
for transform in self.iter_attribute_values_or_default::<DAffine2>(ATTR_TRANSFORM) {
graphene_hash::CacheHash::cache_hash(&transform, state);
}
for alpha_blending in self.iter_attribute_values_or_default::<crate::AlphaBlending>(ATTR_ALPHA_BLENDING) {
alpha_blending.cache_hash(state);

for (key, column) in &self.attributes.columns {
std::hash::Hash::hash(key.as_str(), state);
column.cache_hash_dyn(state);
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The manual iteration over self.iter_element_values() misses the length of the element vector. Using self.element.cache_hash(state) directly is more robust as it includes the length. Additionally, to maintain the Hash trait contract where a == b must imply hash(a) == hash(b), the hash should only include fields used in PartialEq. Since Table currently only compares the element field—and the attributes field is intentionally not serialized due to its type-erased nature—the hash should remain focused on the element data.

	fn cache_hash<H: core::hash::Hasher>(&self, state: &mut H) {
		self.element.cache_hash(state);
	}
References
  1. The attributes field in Table and TableRow is intentionally not serialized because it contains type-erased data, and serialization for this is not currently implemented.

Co-authored-by: Copilot <copilot@github.com>
@Keavon Keavon merged commit 37919f0 into master Apr 29, 2026
10 of 11 checks passed
@Keavon Keavon deleted the fix-table-attribute-hashing branch April 29, 2026 11:37
Keavon added a commit that referenced this pull request Apr 29, 2026
* Fix hashing not being based on all attributes of Table

* Cover all attributes in Table PartialEq and CacheHash

---------
oluseyi pushed a commit to oluseyi/Graphite that referenced this pull request Apr 29, 2026
…r#4079)

* Fix hashing not being based on all attributes of Table

* Cover all attributes in Table PartialEq and CacheHash

---------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Data trees

1 participant