Skip to content

Conversation

ScottDugas
Copy link
Collaborator

@ScottDugas ScottDugas commented Sep 11, 2025

This fixes ResolvedKeySpace.equals and hashCode so that they follow the spec and are consistent.
Notably there were a few issues:

  • They did not correctly handle KeyType.BYTES
  • They disagreed about what data to use (hashCode used to look at the PathValue, while equals looked at the value)
  • PathValue did not implement equals/hashCode
  • The remainder was not included.
  • KeySpacePathImpl redundantly checked the value from the directory
  • It did not check the parent of the ResolvedKeySpacePath.

Fixes: #3594

@ScottDugas ScottDugas added the bug fix Change that fixes a bug label Sep 11, 2025
@ScottDugas ScottDugas marked this pull request as ready for review September 16, 2025 16:12
@ScottDugas ScottDugas requested review from ohadzeliger and removed request for alecgrieser September 17, 2025 19:50
This will be useful when comparing paths, because they can validate
the parent, and don't care about the directiory's other children.
// Handle ANY_VALUE specially - typeOf does not support ANY_VALUE
boolean isAnyValue = (o1 == ANY_VALUE || o2 == ANY_VALUE);
if (isAnyValue) {
return Objects.equals(o1, o2);
Copy link
Contributor

Choose a reason for hiding this comment

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

As a defensive coding we can add equals and hashCode to AnyValue, though all reasonable implementations should use the static constant...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Maybe, but AnyValue is a private-nested class, so KeySpaceDirectory is the only way to construct one, so you really shouldn't be accessing it other than via the constant.

getDirectory().getName(),
getDirectory().getValue(),
getValue(),
KeySpaceDirectory.valueHashCode(getValue()),
Copy link
Contributor

Choose a reason for hiding this comment

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

This would be the same as getDirectory().getValue(), right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Only if the directory is a constant. If the getDirectory().getValue() is ANY_VALUE, this would be any value of that type.

Copy link
Contributor

Choose a reason for hiding this comment

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

In that case there may be a discrepancy where equals (line 281) compares:

  • keyspacePath.value
  • KeyPathDirectory.equalsIgnoringHierarchy ->
    • name
    • KeyType
    • directory.value

Whereas hashCode compares:

  • name
  • keyType
  • keyspacePath.value

So it looks as if the hashCode could benefit from the extra hash for directory.value

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, yes, that is probably true.
It's not catastrophic to have hashCode compare less than equals, especially given that in standard use cases, if everything else is equal, the directory value should be too.
That being said, it would probably be confusing to anyone else coming upon this, so at least it should have a comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug fix Change that fixes a bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ResolvedKeySpacePath.equals/hashCode sometimes are reference equality, and differ
2 participants