Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions convex-core/src/main/java/convex/core/data/AIndex.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package convex.core.data;

import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

import convex.core.data.type.AType;
Expand Down Expand Up @@ -49,9 +49,13 @@ public boolean containsKey(ACell key) {
*/
public abstract V get(K key);

// entryAt(i) walks the radix tree in ascending key order, so a
// LinkedHashSet (which preserves insertion order) is needed here to keep
// that ordering visible through entrySet() — a plain HashSet iterates in
// hash-bucket order and silently discards it (#651).
@Override
public Set<Entry<K, V>> entrySet() {
HashSet<Entry<K,V>> hs=new HashSet<>(size());
LinkedHashSet<Entry<K,V>> hs=new LinkedHashSet<>(size());
long n=count();
for (long i=0; i<n; i++) {
MapEntry<K,V> me=entryAt(i);
Expand Down
21 changes: 21 additions & 0 deletions convex-core/src/test/java/convex/core/data/IndexTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,27 @@ public void testSymbolicKeys() throws InvalidDataException {
doIndexTests(rm);
}

/**
* entrySet() must preserve the Index's sorted key order (#651) — the class
* is documented as "a sorted radix-tree map... provide sorted orderings for
* indexes", and callers commonly iterate entrySet() (e.g. `for (var e :
* index.entrySet())`) expecting that guarantee to hold, not just entryAt(i).
*/
@Test
public void testEntrySetOrder() throws InvalidDataException {
Index<ABlob, CVMLong> m = Index.none();
for (int i = 0; i < 50; i++) {
m = m.assoc(LongBlob.create(i), RT.cvm((long) i));
}
assertEquals(50L, m.count());

java.util.Iterator<java.util.Map.Entry<ABlob, CVMLong>> it = m.entrySet().iterator();
for (long i = 0; i < m.count(); i++) {
assertEquals(m.entryAt(i), it.next(), "entrySet() order diverged from entryAt() sorted order");
}
assertFalse(it.hasNext());
}

@Test public void testContains() {
Index<ABlob, CVMLong> bm=Samples.INT_INDEX_256;
long n=bm.count;
Expand Down