tarun11Mavani commented on code in PR #19093:
URL: https://github.com/apache/pinot/pull/19093#discussion_r4023961348


##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/openstruct/ImmutableOpenStructDataSource.java:
##########
@@ -140,6 +144,141 @@ public JsonIndexReader getSparseJsonIndex() {
     return _sparseDataSource != null ? _sparseDataSource.getJsonIndex() : null;
   }
 
+  @SuppressWarnings("unchecked")
+  @Nullable
+  @Override
+  public Map<String, Object> getMapValue(int docId) {
+    Map<String, Object> result = null;
+
+    for (Map.Entry<String, DataSource> entry : _perKeyDataSources.entrySet()) {
+      Object value = readValue(entry.getKey(), entry.getValue(), docId);
+      if (value != null) {
+        if (result == null) {
+          result = new HashMap<>();
+        }
+        result.put(entry.getKey(), value);
+      }
+    }
+
+    if (_sparseDataSource != null) {
+      Object sparseValue = readValue(_fieldSpec.getName(), _sparseDataSource, 
docId);
+      if (sparseValue instanceof String) {
+        String json = (String) sparseValue;
+        if (!json.isEmpty()) {
+          try {
+            Map<String, Object> sparseMap = JsonUtils.stringToObject(json, 
Map.class);
+            if (result == null) {
+              result = new HashMap<>();
+            }
+            result.putAll(sparseMap);
+          } catch (IOException e) {
+            throw new RuntimeException("Failed to parse sparse JSON at docId " 
+ docId, e);
+          }
+        }
+      }
+    }
+
+    return result;
+  }
+
+  /// Reads the value of `key` at `docId`, or `null` when the doc is null or 
the column has no
+  /// forward index. Delegates the null-vector check and the dictionary/raw 
per-type read dispatch to
+  /// [PinotSegmentColumnReader] rather than re-deriving them here, so this 
path cannot drift from the
+  /// reader every other column read in the engine already goes through. 
OPEN_STRUCT child columns are
+  /// always single-valued, hence the 0 maxNumValuesPerMVEntry.
+  @Nullable
+  private static Object readValue(String key, DataSource dataSource, int 
docId) {
+    ForwardIndexReader<?> fwdReader = dataSource.getForwardIndex();
+    if (fwdReader == null) {
+      return null;
+    }
+    try (PinotSegmentColumnReader reader = new PinotSegmentColumnReader(key, 
fwdReader, dataSource.getDictionary(),
+        dataSource.getNullValueVector(), 0)) {
+      return reader.isNull(docId) ? null : reader.getValue(docId);
+    } catch (Exception e) {
+      throw new RuntimeException("Failed to read value from OPEN_STRUCT key 
forward index", e);
+    }
+  }
+
+  @Override
+  public MapValueReader openMapValueReader() {
+    return new CachingMapValueReader();
+  }
+
+  /// Caches one [PinotSegmentColumnReader] per key for the life of the 
reader, instead of the
+  /// per-call construct-and-close [#readValue]/[#getMapValue] does. For a 
raw, chunk-compressed
+  /// column (e.g. the sparse blob), a fresh reader per doc means a fresh 
decompression buffer and,
+  /// depending on access order, redundant re-decompression of the same chunk; 
reusing the reader
+  /// across a sequential scan lets it carry its decoded-chunk state forward. 
Not thread-safe — for
+  /// one single-threaded scan only, per 
[OpenStructDataSource#openMapValueReader()].
+  private final class CachingMapValueReader implements MapValueReader {
+    private final Map<String, PinotSegmentColumnReader> _readers = new 
HashMap<>();
+
+    @SuppressWarnings("unchecked")
+    @Nullable
+    @Override
+    public Map<String, Object> getMapValue(int docId) {

Review Comment:
    Done — getMapValue() now delegates via try-with-resources to 
openMapValueReader().



-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to