Skip to content

Commit a7307eb

Browse files
dfa1claude
andcommitted
fix(sonar): size hash-based collections with the JDK 19+ factory methods (S6485)
new HashSet<>(n)/new HashMap<>(n)/new LinkedHashMap<>(n) treat n as raw initial capacity, not expected entry count -- undersized relative to the 0.75 load factor, so these were one resize away from their stated bound in the worst case (the manual "+1" fudges in DictColumnState show the sizing was already an approximation). HashSet.newHashSet(n) / HashMap.newHashMap(n) / LinkedHashMap.newLinkedHashMap(n) take the actual expected element count and size correctly, guaranteed no resize. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KW6yskY3pE759XUg2UUtf8
1 parent 8bca285 commit a7307eb

3 files changed

Lines changed: 9 additions & 9 deletions

File tree

‎reader/src/main/java/io/github/dfa1/vortex/reader/ScanIterator.java‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ private static SequencedMap<ColumnName, Chunk.Column> expandStruct(StructArray s
255255
List<ColumnName> names = sd.fieldNames();
256256
List<DType> types = sd.fieldTypes();
257257
int n = names.size();
258-
var map = new LinkedHashMap<ColumnName, Chunk.Column>(n);
258+
var map = LinkedHashMap.<ColumnName, Chunk.Column>newLinkedHashMap(n);
259259
for (int i = 0; i < n; i++) {
260260
map.put(names.get(i), new Chunk.Column(sa.field(i), types.get(i)));
261261
}
@@ -266,7 +266,7 @@ private static SequencedMap<ColumnName, Chunk.Column> expandStruct(StructArray s
266266

267267
private static SequencedMap<ColumnName, Chunk.Column> limitedColumns(
268268
SequencedMap<ColumnName, Chunk.Column> columns, long rows) {
269-
var result = new LinkedHashMap<ColumnName, Chunk.Column>(columns.size());
269+
var result = LinkedHashMap.<ColumnName, Chunk.Column>newLinkedHashMap(columns.size());
270270
for (var entry : columns.entrySet()) {
271271
Chunk.Column col = entry.getValue();
272272
result.put(entry.getKey(), new Chunk.Column(Array.limited(col.array(), rows), col.dtype()));
@@ -669,7 +669,7 @@ private SequencedMap<ColumnName, Chunk.Column> buildColumnMap(ChunkSpec chunk, A
669669
}
670670
return singleColumn(arr);
671671
}
672-
var scratch = new LinkedHashMap<ColumnName, Chunk.Column>(n);
672+
var scratch = LinkedHashMap.<ColumnName, Chunk.Column>newLinkedHashMap(n);
673673
for (int i = 0; i < n; i++) {
674674
scratch.put(projectedNames.get(i), new Chunk.Column(
675675
decodeOrSlice(i, layouts[i], sliceOffsets[i], chunk.rowCount(), arena),
@@ -692,7 +692,7 @@ private SequencedMap<ColumnName, Chunk.Column> buildSelfContainedColumnMap(Chunk
692692
}
693693
return singleColumn(arr);
694694
}
695-
var scratch = new LinkedHashMap<ColumnName, Chunk.Column>(n);
695+
var scratch = LinkedHashMap.<ColumnName, Chunk.Column>newLinkedHashMap(n);
696696
for (int i = 0; i < n; i++) {
697697
scratch.put(projectedNames.get(i), new Chunk.Column(
698698
decodeOrSliceSelfContained(i, layouts[i], sliceOffsets[i], chunk.rowCount(), arena),
@@ -702,7 +702,7 @@ private SequencedMap<ColumnName, Chunk.Column> buildSelfContainedColumnMap(Chunk
702702
}
703703

704704
private SequencedMap<ColumnName, Chunk.Column> singleColumn(Array array) {
705-
var map = new LinkedHashMap<ColumnName, Chunk.Column>(1);
705+
var map = LinkedHashMap.<ColumnName, Chunk.Column>newLinkedHashMap(1);
706706
map.put(projectedNames.getFirst(), new Chunk.Column(array, projectedDtypes.getFirst()));
707707
return unmodifiable(map);
708708
}

‎writer/src/main/java/io/github/dfa1/vortex/writer/DictColumnState.java‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ boolean ingestDictChunk(Object data) {
147147
// First pass: would this chunk's fresh distinct values push the map past the cap? Count them
148148
// without mutating so the whole chunk is either ingested or rejected atomically — a partial
149149
// ingest would corrupt the dictionary when the caller demotes on rejection.
150-
var pendingNew = new HashSet<>(Math.min(cap, len) + 1);
150+
var pendingNew = HashSet.newHashSet(Math.min(cap, len));
151151
for (int i = 0; i < len; i++) {
152152
if (validity != null && !validity[i]) {
153153
continue;
@@ -387,7 +387,7 @@ static boolean isUtf8DictCandidate(String[] data, boolean[] validity) {
387387
if (data.length == 0) {
388388
return false;
389389
}
390-
var seen = new java.util.HashSet<String>(Math.min(GLOBAL_DICT_MAX_CARDINALITY_UTF8, data.length) + 1);
390+
var seen = HashSet.<String>newHashSet(Math.min(GLOBAL_DICT_MAX_CARDINALITY_UTF8, data.length));
391391
for (int i = 0; i < data.length; i++) {
392392
if ((validity != null && !validity[i]) || data[i] == null) {
393393
continue;
@@ -438,7 +438,7 @@ static boolean isDictCandidate(PType ptype, Object data, boolean[] validity) {
438438
if (n == 0) {
439439
return false;
440440
}
441-
var seen = new HashSet<>(GLOBAL_DICT_MAX_CARDINALITY + 1);
441+
var seen = HashSet.newHashSet(GLOBAL_DICT_MAX_CARDINALITY);
442442
for (int i = 0; i < n; i++) {
443443
if (validity != null && !validity[i]) {
444444
continue;

‎writer/src/main/java/io/github/dfa1/vortex/writer/encode/ArrayStats.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static ArrayStats compute(PType ptype, Object data, StatsOptions options)
4444
return new ArrayStats(n, -1, 0, 0);
4545
}
4646
HashMap<Long, int[]> counts = options.countDistinct() || options.trackMostFrequent()
47-
? new HashMap<>(Math.min(n, 1 << 16))
47+
? HashMap.newHashMap(Math.min(n, 1 << 16))
4848
: null;
4949
long topFreqBits = 0;
5050
int topFreq = 0;

0 commit comments

Comments
 (0)