Skip to content

Commit b1749a4

Browse files
committed
Specialise filtering for Ref arrays in Sets and Maps
1 parent 9e5779e commit b1749a4

File tree

4 files changed

+53
-76
lines changed

4 files changed

+53
-76
lines changed

convex-core/src/main/java/convex/core/data/MapTree.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,19 @@ public static <K extends ACell, V extends ACell> MapTree<K, V> create(MapEntry<K
102102
*/
103103
private static <K extends ACell, V extends ACell> AHashMap<K, V> createFull(Ref<AHashMap<K, V>>[] children, int shift, long count) {
104104
if (children.length != FANOUT) throw new IllegalArgumentException("16 children required!");
105-
Ref<AHashMap<K, V>>[] newChildren = Utils.filterArray(children, a -> {
106-
if (a == null) return false;
107-
AMap<K, V> m = a.getValue();
108-
return ((m != null) && !m.isEmpty());
109-
});
110-
111-
if (children != newChildren) {
112-
return create(newChildren, shift, Utils.computeMask(children, newChildren), count);
113-
} else {
114-
return create(children, shift, (short) 0xFFFF, count);
105+
int mask=0;
106+
for (int i=0; i<FANOUT; i++) {
107+
Ref<AHashMap<K, V>> ch=children[i];
108+
if (ch!=null) {
109+
AMap<K, V> m = ch.getValue();
110+
if ((m!=null)&&(!m.isEmpty())) {
111+
mask|=(1<<i);
112+
}
113+
}
115114
}
115+
if (mask==0xFFFF) return create(children, shift, (short) 0xFFFF, count);
116+
Ref<AHashMap<K, V>>[] newChildren = Refs.filterSmallArray(children, mask);
117+
return create(newChildren, shift, (short)mask, count);
116118
}
117119

118120
/**
@@ -171,7 +173,7 @@ private static <K extends ACell, V extends ACell> AHashMap<K, V> create(Ref<AHas
171173
}
172174
}
173175
if (mask != newMask) {
174-
return new MapTree<K, V>(Utils.filterSmallArray(children, sel), shift, newMask, count);
176+
return new MapTree<K, V>(Refs.filterSmallArray(children, sel), shift, newMask, count);
175177
}
176178
return new MapTree<K, V>(children, shift, mask, count);
177179
}

convex-core/src/main/java/convex/core/data/Refs.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,31 @@ private static void printTree(StringBuilder sb, Ref<ACell> ref, int indent) {
190190
}
191191
}
192192

193+
/**
194+
* Filters an array of Refs, returning an array containing only the elements where the
195+
* mask bit is set. May return the same array if all elements areincluded.
196+
*
197+
* @param arr Array to filter
198+
* @param mask Mask of elements to include
199+
* @return Filtered array.
200+
*/
201+
@SuppressWarnings("unchecked")
202+
public static <T extends ACell> Ref<T>[] filterSmallArray(Ref<T>[] arr, int mask) {
203+
int n = arr.length;
204+
if (n > 32) throw new IllegalArgumentException("Array too long to filter: " + n);
205+
int fullMask = (1 << n) - 1;
206+
if (mask == fullMask) return arr;
207+
int nn = Integer.bitCount(mask);
208+
Ref<T>[] result = new Ref[nn];
209+
if (nn == 0) return result;
210+
int ix = 0;
211+
for (int i = 0; i < n; i++) {
212+
if ((mask & (1 << i)) != 0) {
213+
result[ix++] = arr[i];
214+
}
215+
}
216+
assert (ix == nn);
217+
return result;
218+
}
219+
193220
}

convex-core/src/main/java/convex/core/data/SetTree.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,19 @@ public static <V extends ACell> SetTree<V> create(Ref<V>[] elementRefs, int shif
104104
*/
105105
private static <T extends ACell> AHashSet<T> createFull(Ref<AHashSet<T>>[] children, int shift, long count) {
106106
if (children.length != 16) throw new IllegalArgumentException("16 children required!");
107-
Ref<AHashSet<T>>[] newChildren = Utils.filterArray(children, a -> {
108-
if (a == null) return false;
109-
AHashSet<T> m = a.getValue();
110-
return ((m != null) && !m.isEmpty());
111-
});
112-
113-
if (children != newChildren) {
114-
return create(newChildren, shift, Utils.computeMask(children, newChildren), count);
115-
} else {
116-
return create(children, shift, (short) 0xFFFF, count);
107+
int mask=0;
108+
for (int i=0; i<16; i++) {
109+
Ref<AHashSet<T>> ch=children[i];
110+
if (ch!=null) {
111+
AHashSet<T> m = ch.getValue();
112+
if ((m!=null)&&(!m.isEmpty())) {
113+
mask|=(1<<i);
114+
}
115+
}
117116
}
117+
if (mask==0xFFFF) return create(children, shift, (short) 0xFFFF, count);
118+
Ref<AHashSet<T>>[] newChildren = Refs.filterSmallArray(children, mask);
119+
return create(newChildren, shift, (short)mask, count);
118120
}
119121

120122
/**
@@ -173,7 +175,7 @@ private static <V extends ACell> AHashSet<V> create(Ref<AHashSet<V>>[] children,
173175
}
174176
}
175177
if (mask != newMask) {
176-
return new SetTree<V>(Utils.filterSmallArray(children, sel), shift, newMask, count);
178+
return new SetTree<V>(Refs.filterSmallArray(children, sel), shift, newMask, count);
177179
}
178180
return new SetTree<V>(children, shift, mask, count);
179181
}

convex-core/src/main/java/convex/core/util/Utils.java

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.List;
2121
import java.util.Random;
2222
import java.util.function.Function;
23-
import java.util.function.Predicate;
2423
import java.util.function.Supplier;
2524
import java.util.stream.Collectors;
2625

@@ -858,59 +857,6 @@ public int compare(T a, T b) {
858857
});
859858
return result;
860859
}
861-
862-
/**
863-
* Filters the array, returning an array containing only the elements where the
864-
* predicate returns true. May return the same array if all elements are
865-
* included.
866-
*
867-
* @param arr Array to filter
868-
* @param predicate Predicate to test array elements
869-
* @return Filtered array.
870-
*/
871-
public static <T> T[] filterArray(T[] arr, Predicate<T> predicate) {
872-
if (arr.length <= 32) return filterSmallArray(arr, predicate);
873-
throw new IllegalArgumentException("Can't Filter large arrays");
874-
}
875-
876-
/**
877-
* Filters the array, returning an array containing only the elements where the
878-
* predicate returns true. May return the same array if all elements are
879-
* included.
880-
*
881-
* Array must have a maximum of 32 elements
882-
*
883-
* @param arr
884-
* @param predicate
885-
* @return
886-
*/
887-
private static <T> T[] filterSmallArray(T[] arr, Predicate<T> predicate) {
888-
int mask = 0;
889-
int n = arr.length;
890-
for (int i = 0; i < n; i++) {
891-
if (predicate.test(arr[i])) mask |= (1 << i);
892-
}
893-
return filterSmallArray(arr, mask);
894-
}
895-
896-
@SuppressWarnings("unchecked")
897-
public static <T> T[] filterSmallArray(T[] arr, int mask) {
898-
int n = arr.length;
899-
if (n > 32) throw new IllegalArgumentException("Array too long to filter: " + n);
900-
int fullMask = (1 << n) - 1;
901-
if (mask == fullMask) return arr;
902-
int nn = Integer.bitCount(mask);
903-
T[] result = (T[]) Array.newInstance(arr.getClass().getComponentType(), nn);
904-
if (nn == 0) return result;
905-
int ix = 0;
906-
for (int i = 0; i < n; i++) {
907-
if ((mask & (1 << i)) != 0) {
908-
result[ix++] = arr[i];
909-
}
910-
}
911-
assert (ix == nn);
912-
return result;
913-
}
914860

915861
/**
916862
* Computes a bit mask of up to 16 bits by scanning a full array for which

0 commit comments

Comments
 (0)