Skip to content

Commit

Permalink
add consumer code to account for the bad scenario to allow to exit ou…
Browse files Browse the repository at this point in the history
…t of bad blobs
  • Loading branch information
eduardoramirez committed Dec 20, 2024
1 parent 400e645 commit db8e046
Showing 1 changed file with 16 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,14 @@ public void applyDelta() {
target.bitsPerMapPointer = delta.bitsPerMapPointer;
target.bitsPerMapSizeValue = delta.bitsPerMapSizeValue;
target.bitsPerKeyElement = delta.bitsPerKeyElement;
target.bitsPerValueElement = delta.bitsPerValueElement;
// Prior to Jan 2025, the producer was able to generate blobs where it reserved 0 bits for the Map value
// element when all keys stored the same record and that record's ordinal was 0. In this case, when reading the
// Map value of the last bucket, the code would trigger ArrayIndexOutOfBoundsException since there was no space
// allocated for the value element. This is a workaround to avoid the exception when transitioning out of one
// of these bad blobs.
target.bitsPerValueElement = delta.bitsPerValueElement == 0 ? 1 : delta.bitsPerValueElement;
target.bitsPerFixedLengthMapPortion = delta.bitsPerFixedLengthMapPortion;
target.bitsPerMapEntry = delta.bitsPerMapEntry;
target.bitsPerMapEntry = target.bitsPerKeyElement + target.bitsPerValueElement;
target.emptyBucketKeyValue = delta.emptyBucketKeyValue;
target.totalNumberOfBuckets = delta.totalNumberOfBuckets;

Expand Down Expand Up @@ -143,7 +148,15 @@ private void mergeOrdinal(int ordinal) {
if(!removeData) {
for(long bucketIdx=currentFromStateStartBucket; bucketIdx<fromDataEndBucket; bucketIdx++) {
long bucketKey = from.entryData.getElementValue(bucketIdx * from.bitsPerMapEntry, from.bitsPerKeyElement);
long bucketValue = from.entryData.getElementValue(bucketIdx * from.bitsPerMapEntry + from.bitsPerKeyElement, from.bitsPerValueElement);
// Prior to Jan 2025, the producer was able to generate blobs where it reserved 0 bits for the Map value
// element when all keys stored the same record and that record's ordinal was 0. In this case, when reading the
// Map value of the last bucket, the code would trigger ArrayIndexOutOfBoundsException since there was no space
// allocated for the value element. This is a workaround to avoid the exception when transitioning out of one
// of these bad blobs.
long bucketValue =
from.bitsPerValueElement == 0
? 0
: from.entryData.getElementValue(bucketIdx * from.bitsPerMapEntry + from.bitsPerKeyElement, from.bitsPerValueElement);
if(bucketKey == from.emptyBucketKeyValue)
bucketKey = target.emptyBucketKeyValue;
long currentWriteStartBucketBit = currentWriteStartBucket * target.bitsPerMapEntry;
Expand Down

0 comments on commit db8e046

Please sign in to comment.