Assigned
Status Update
Comments
du...@google.com <du...@google.com>
ap...@google.com <ap...@google.com> #2
Please include a sample project that reproduces your issue.
No update yet.
Please include a sample project that reproduces your issue.
Description
Namely, for performance reasons, SparseArray does not immediately "gc" when an element is removed by shrinking the backing array and replacing holes. This is _usually_ invisible to the client, because _almost_ all methods (such as keyAt, indexOfKey, valueAt, indexOfValue, and setValueAt) that take an index to the backing array as an argument first "gc" the backing array. But removeAt does not, resulting in the below oddity, where two sequences of calls that differ only in a call to the "size" accessor result in different behavior.
It's tempting just to call this a bug and fix it, but I'm concerned that there may be clients that (wittingly or no) depend on this behavior, and will break if we fix it. Thoughts? Happy to stage a fix if we decide that's the right way forward.
@Test
fun removeAtBehavior() {
val a = SparseArray<String>().apply {
put(1, "one")
put(10, "ten")
put(100, "one hundred")
put(1000, "one thousand")
}
a.removeAt(2)
a.removeAt(2)
assertEquals(3, a.size)
val b = SparseArray<String>().apply {
put(1, "one")
put(10, "ten")
put(100, "one hundred")
put(1000, "one thousand")
}
b.removeAt(2)
// This is a load-bearing accessor call! Changes the behavior of the next removeAt
b.size
b.removeAt(2)
assertEquals(2, b.size)
}