iemejia commented on code in PR #3927:
URL: https://github.com/apache/avro/pull/3927#discussion_r3735596035


##########
lang/java/avro/src/main/java/org/apache/avro/io/FastReaderBuilder.java:
##########
@@ -481,33 +481,29 @@ private FieldReader createArrayReader(Schema 
readerSchema, Container action) thr
       if (reuse instanceof GenericArray) {
         GenericArray<Object> reuseArray = (GenericArray<Object>) reuse;
         long l = decoder.readArrayStart();
-        long total = 0;
-        checkArrayBlock(decoder, elementType, zeroByteElements, total, l);
+        checkArrayBlock(decoder, elementType, zeroByteElements, l);

Review Comment:
   Good catch. Fixed in `createArrayReader`: the returned array reader now 
opens a `beginCollectionAllocationScope()` around the block-reading loop. When 
the fast reader is entered through `GenericDatumReader.read` the scope simply 
nests and accumulates into the outer datum scope (only the outermost resets the 
running total); when the fast reader is used standalone via 
`createDatumReader(...)` the scope makes the zero-byte cap cumulative across 
all array blocks of the datum instead of degrading to a per-block stateless 
check. So a large `array<null>`-style array split across many blocks can no 
longer bypass the cap. (66750cb)



##########
lang/java/avro/src/main/java/org/apache/avro/io/FastReaderBuilder.java:
##########
@@ -481,33 +481,29 @@ private FieldReader createArrayReader(Schema 
readerSchema, Container action) thr
       if (reuse instanceof GenericArray) {
         GenericArray<Object> reuseArray = (GenericArray<Object>) reuse;
         long l = decoder.readArrayStart();
-        long total = 0;
-        checkArrayBlock(decoder, elementType, zeroByteElements, total, l);
+        checkArrayBlock(decoder, elementType, zeroByteElements, l);
         reuseArray.clear();
 
         while (l > 0) {
           for (long i = 0; i < l; i++) {
             reuseArray.add(elementReader.read(reuseArray.peek(), decoder));
           }
-          total += l;
           l = decoder.arrayNext();
-          checkArrayBlock(decoder, elementType, zeroByteElements, total, l);
+          checkArrayBlock(decoder, elementType, zeroByteElements, l);
         }
         return reuseArray;
       } else {
         long l = decoder.readArrayStart();
-        long total = 0;
-        checkArrayBlock(decoder, elementType, zeroByteElements, total, l);
+        checkArrayBlock(decoder, elementType, zeroByteElements, l);
         List<Object> array = (reuse instanceof List) ? (List<Object>) reuse
             : new 
GenericData.Array<>(GenericDatumReader.initialCollectionCapacity(l), 
readerSchema);
         array.clear();
         while (l > 0) {
           for (long i = 0; i < l; i++) {
             array.add(elementReader.read(null, decoder));
           }
-          total += l;
           l = decoder.arrayNext();
-          checkArrayBlock(decoder, elementType, zeroByteElements, total, l);
+          checkArrayBlock(decoder, elementType, zeroByteElements, l);
         }
         return array;
       }

Review Comment:
   Done — the scope is opened and closed in a `try/finally` that wraps both the 
reuse and non-reuse branches, so it is always closed and ThreadLocal state 
cannot leak into later decodes on the same thread. This keeps the zero-byte 
element accounting cumulative across every array block in the read even when 
the fast reader is used standalone. (66750cb)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to