Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PeristentHashMapBuilder.putAll() with another persistent hash map can produce incorrect results. #114

Closed
chuckjaz opened this issue Jul 14, 2021 · 8 comments
Assignees

Comments

@chuckjaz
Copy link

Consider the following code:

val p = persistentHashMapOf<Int, Int>(99 to 1)
val e = Array(101) { it }.map { it to it }
val c = persistentHashMapOf(*e.toTypedArray())
val n = p.builder().apply { putAll(c) }.build()
println("n[99] = ${n[99]}")

Expected

n[99] = 99

Received

n[99] = 1

Changing the putAll call above to putAll(e) produces the expected result.

@chuckjaz
Copy link
Author

The was originally found in Compose: https://issuetracker.google.com/issues/193433239

@qurbonzoda qurbonzoda self-assigned this Jul 15, 2021
@chuckjaz
Copy link
Author

The issue appears to me to be centered around this line,

https://github.com/Kotlin/kotlinx.collections.immutable/blob/master/core/commonMain/src/implementations/immutableMap/TrieNode.kt#L607

It inverts the other and this in a way that causes the old values to be given preference to new values. If this code executes it appears to be in danger of producing the wrong value. The fix for this is not obvious to me. I couldn't think of something that wasn't brutally direct .

chuckjaz added a commit to chuckjaz/kotlinx.collections.immutable that referenced this issue Jul 15, 2021
@chuckjaz
Copy link
Author

I created a candidate fix in #115. This seems to work when I test it in the Compose local copy of this code.

qurbonzoda pushed a commit that referenced this issue Jul 15, 2021
… produce incorrect results #114

When putting all entries of a cell (1) into another cell (2), if (1) is an entry and (2) is a node, for optimization reasons the entry is put into the node. This leads to saving the old value of the entry if the node already contains the key.
@qurbonzoda
Copy link
Contributor

@chuckjaz do you need an immediate release with the fix?

@chuckjaz
Copy link
Author

No. We use a renamed copy of this code because it is not stable. A fix that you approve of would be sufficient then I will cherry-pick the change into our sources.

@chuckjaz
Copy link
Author

When the #116 lands I will cherry-pick the result into our sources.

@qurbonzoda
Copy link
Contributor

Understood.
Thank you for the bug report, by the way.

@chuckjaz
Copy link
Author

chuckjaz commented Jul 15, 2021

It was @igordmn's original report. I just narrowed it down a bit further.

qurbonzoda pushed a commit that referenced this issue Jul 19, 2021
… produce incorrect results #114

When putting all entries of a cell (1) into another cell (2), if (1) is an entry and (2) is a node, for optimization reasons the entry is put into the node. This leads to saving the old value of the entry if the node already contains the key.
qurbonzoda pushed a commit that referenced this issue Jul 19, 2021
… produce incorrect results #114

When putting all entries of a cell (1) into another cell (2), if (1) is an entry and (2) is a node, for optimization reasons the entry is put into the node. This leads to saving the old value of the entry if the node already contains the key.
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

No branches or pull requests

2 participants