in hollow/src/main/java/com/netflix/hollow/core/write/HollowListTypeWriteState.java [239:310]
public void calculateDelta(ThreadSafeBitSet fromCyclePopulated, ThreadSafeBitSet toCyclePopulated, boolean isReverse) {
int numShards = this.numShards;
int bitsPerListPointer = this.bitsPerListPointer;
if (isReverse && this.numShards != this.revNumShards) {
numShards = this.revNumShards;
bitsPerListPointer = this.revBitsPerListPointer;
}
numListsInDelta = new int[numShards];
numElementsInDelta = new long[numShards];
listPointerArray = new FixedLengthElementArray[numShards];
elementArray = new FixedLengthElementArray[numShards];
deltaAddedOrdinals = new ByteDataArray[numShards];
deltaRemovedOrdinals = new ByteDataArray[numShards];
ThreadSafeBitSet deltaAdditions = toCyclePopulated.andNot(fromCyclePopulated);
int shardMask = numShards - 1;
int addedOrdinal = deltaAdditions.nextSetBit(0);
while(addedOrdinal != -1) {
numListsInDelta[addedOrdinal & shardMask]++;
long readPointer = ordinalMap.getPointerForData(addedOrdinal);
numElementsInDelta[addedOrdinal & shardMask] += VarInt.readVInt(ordinalMap.getByteData().getUnderlyingArray(), readPointer);
addedOrdinal = deltaAdditions.nextSetBit(addedOrdinal + 1);
}
for(int i=0;i<numShards;i++) {
listPointerArray[i] = new FixedLengthElementArray(WastefulRecycler.DEFAULT_INSTANCE, (long)numListsInDelta[i] * bitsPerListPointer);
elementArray[i] = new FixedLengthElementArray(WastefulRecycler.DEFAULT_INSTANCE, numElementsInDelta[i] * bitsPerElement);
deltaAddedOrdinals[i] = new ByteDataArray(WastefulRecycler.DEFAULT_INSTANCE);
deltaRemovedOrdinals[i] = new ByteDataArray(WastefulRecycler.DEFAULT_INSTANCE);
}
ByteData data = ordinalMap.getByteData().getUnderlyingArray();
int listCounter[] = new int[numShards];
long elementCounter[] = new long[numShards];
int previousRemovedOrdinal[] = new int[numShards];
int previousAddedOrdinal[] = new int[numShards];
for(int ordinal=0;ordinal<=maxOrdinal;ordinal++) {
int shardNumber = ordinal & shardMask;
if(deltaAdditions.get(ordinal)) {
long readPointer = ordinalMap.getPointerForData(ordinal);
int size = VarInt.readVInt(data, readPointer);
readPointer += VarInt.sizeOfVInt(size);
listPointerArray[shardNumber].setElementValue((long)bitsPerListPointer * listCounter[shardNumber], bitsPerListPointer, elementCounter[shardNumber] + size);
for(int j=0;j<size;j++) {
int elementOrdinal = VarInt.readVInt(data, readPointer);
readPointer += VarInt.sizeOfVInt(elementOrdinal);
elementArray[shardNumber].setElementValue((long)bitsPerElement * elementCounter[shardNumber], bitsPerElement, elementOrdinal);
elementCounter[shardNumber]++;
}
listCounter[shardNumber]++;
int shardOrdinal = ordinal / numShards;
VarInt.writeVInt(deltaAddedOrdinals[shardNumber], shardOrdinal - previousAddedOrdinal[shardNumber]);
previousAddedOrdinal[shardNumber] = shardOrdinal;
} else if(fromCyclePopulated.get(ordinal) && !toCyclePopulated.get(ordinal)) {
int shardOrdinal = ordinal / numShards;
VarInt.writeVInt(deltaRemovedOrdinals[shardNumber], shardOrdinal - previousRemovedOrdinal[shardNumber]);
previousRemovedOrdinal[shardNumber] = shardOrdinal;
}
}
}