in spark-load/spark-load-common/src/main/java/org/apache/doris/common/io/Roaring64Map.java [713:779]
private void ensureOne(Map.Entry<Integer, BitmapDataProvider> e, int currentHigh, int indexOk) {
// sortedHighs are valid only up to some index
assert indexOk <= sortedHighs.length : indexOk + " is bigger than " + sortedHighs.length;
final int index;
if (indexOk == 0) {
if (sortedHighs.length == 0) {
index = -1;
// } else if (sortedHighs[0] == currentHigh) {
// index = 0;
} else {
index = -1;
}
} else if (indexOk < sortedHighs.length) {
index = -indexOk - 1;
} else {
index = -sortedHighs.length - 1;
}
assert index == binarySearch(sortedHighs, 0, indexOk, currentHigh) : "Computed " + index
+ " differs from dummy binary-search index: "
+ binarySearch(sortedHighs, 0, indexOk, currentHigh);
if (index >= 0) {
// This would mean calling .ensureOne is useless: should never got here at the first time
throw new IllegalStateException("Unexpectedly found " + currentHigh + " in "
+ Arrays.toString(sortedHighs) + " strictly before index" + indexOk);
} else {
int insertionPosition = -index - 1;
// This is a new key
if (insertionPosition >= sortedHighs.length) {
int previousSize = sortedHighs.length;
// TODO softer growing factor
int newSize = Math.min(Integer.MAX_VALUE, sortedHighs.length * 2 + 1);
// Insertion at the end
sortedHighs = Arrays.copyOf(sortedHighs, newSize);
sortedCumulatedCardinality = Arrays.copyOf(sortedCumulatedCardinality, newSize);
// Not actually needed. But simplify the reading of array content
Arrays.fill(sortedHighs, previousSize, sortedHighs.length, highestHigh());
Arrays.fill(sortedCumulatedCardinality, previousSize, sortedHighs.length, Long.MAX_VALUE);
}
sortedHighs[insertionPosition] = currentHigh;
final long previousCardinality;
if (insertionPosition >= 1) {
previousCardinality = sortedCumulatedCardinality[insertionPosition - 1];
} else {
previousCardinality = 0;
}
sortedCumulatedCardinality[insertionPosition] =
previousCardinality + e.getValue().getLongCardinality();
if (currentHigh == highestHigh()) {
// We are already on the highest high. Do not set allValid as it is set anyway out of the
// loop
firstHighNotValid = currentHigh;
} else {
// The first not valid is the next high
// TODO: The entry comes from a NavigableMap: it may be quite cheap to know the next high
firstHighNotValid = currentHigh + 1;
}
}
}