raghavyadav01 commented on code in PR #19897:
URL: https://github.com/apache/pinot/pull/19897#discussion_r4365658050


##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/text/LuceneTextIndexCreator.java:
##########
@@ -331,6 +313,17 @@ public void add(String[] documents, int length) {
     }
   }
 
+  private void addDocIdFields(Document document) {
+    int docId = _nextDocId++;
+    // Keep the stored field for older readers. Immutable indexes add doc 
values to avoid decompressing every stored
+    // document on segment load and retain the actual Pinot id when Lucene 
flushes or merges reorder documents.
+    document.add(new StoredField(PINOT_DOC_ID_STORED_FIELD_NAME, docId));
+    // A TEXT column with this name must keep the stored-field fallback to 
avoid conflicting Lucene field schemas.
+    if (_commitOnClose && 
!_textColumn.equals(PINOT_DOC_ID_DOC_VALUES_FIELD_NAME)) {

Review Comment:
   With storeInSegmentFile=true, the mapping is built once in close() and the 
reader uses the persisted buffer from then on, so these doc values are never 
read again but still add ~10% to the index (and to tiered/remote downloads). 
Same for TryOptimize/Default after the first load. Can we skip the doc values 
when storeInSegmentFile is true, or make them opt-in?



##########
pinot-segment-local/src/test/java/org/apache/pinot/segment/local/segment/index/creator/LuceneTextIndexCreatorTest.java:
##########
@@ -111,9 +118,84 @@ public void testIndexWriterReaderMatchWithOrClause()
     // Use TextIndex reader to validate that reads work
     try (LuceneTextIndexReader reader = new LuceneTextIndexReader("foo", 
INDEX_DIR, 5, new HashMap<>())) {
       int[] matchedDocIds = reader.getDocIds("retain|keep").toArray();
-      Assert.assertEquals(matchedDocIds.length, 2);
-      Assert.assertEquals(matchedDocIds[0], 1);
-      Assert.assertEquals(matchedDocIds[1], 2);
+      assertEquals(matchedDocIds.length, 2);
+      assertEquals(matchedDocIds[0], 1);
+      assertEquals(matchedDocIds[1], 2);
+    }
+  }
+
+  @Test
+  public void testDocValuesRetainStoredIdsForSingleAndMultiValueDocuments()

Review Comment:
   Could we add coverage for storeInSegmentFile=true? That includes the 
combined .text file read via LuceneTextIndexBufferReader, and an older combined 
file with no mapping buffer falling back to fillDocIdMapping.



##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/store/TextIndexUtils.java:
##########
@@ -89,6 +95,63 @@ public void onChange(Set<String> changedConfigs, Map<String, 
String> clusterConf
     }
   }
 
+  /// Reads the actual Pinot ids after Lucene merges and sorting, optionally 
remapping mutable ids during conversion.
+  /// Doc values avoid stored-field decompression. Mutable indexes contain 
only the stored field; older immutable
+  /// indexes and documents without doc values also use the per-document 
stored-field fallback.
+  /// Returns whether the final mapping is the identity mapping.
+  public static boolean fillDocIdMapping(IndexReader indexReader, 
PinotDataBuffer buffer, int numDocs,
+      @Nullable int[] mutableToImmutableDocIdMap)
+      throws IOException {
+    NumericDocValues pinotDocIdValues =
+        MultiDocValues.getNumericValues(indexReader, 
LuceneTextIndexCreator.PINOT_DOC_ID_DOC_VALUES_FIELD_NAME);
+    PinotDocIdVisitor visitor = new PinotDocIdVisitor();
+    StoredFields storedFields = null;
+    boolean isIdentityMapping = true;
+    for (int luceneDocId = 0; luceneDocId < numDocs; luceneDocId++) {
+      int pinotDocId;
+      if (pinotDocIdValues != null && 
pinotDocIdValues.advanceExact(luceneDocId)) {
+        pinotDocId = Math.toIntExact(pinotDocIdValues.longValue());
+      } else {
+        if (storedFields == null) {
+          storedFields = indexReader.storedFields();
+        }
+        visitor._pinotDocId = Integer.MIN_VALUE;
+        storedFields.document(luceneDocId, visitor);
+        pinotDocId = visitor._pinotDocId;
+        if (pinotDocId == Integer.MIN_VALUE) {
+          throw new IOException("Missing Pinot document id for Lucene 
document: " + luceneDocId);
+        }
+      }
+      if (mutableToImmutableDocIdMap != null) {
+        // Conversion can reorder Pinot rows independently of Lucene's own 
document order.
+        pinotDocId = mutableToImmutableDocIdMap[pinotDocId];
+      }
+      isIdentityMapping &= luceneDocId == pinotDocId;
+      buffer.putInt((long) luceneDocId * Integer.BYTES, pinotDocId);
+    }
+    return isIdentityMapping;

Review Comment:
   close() ignores this return value when storeInSegmentFile is true, so an 
identity mapping file still gets written, and the reader then always builds a 
DefaultDocIdTranslator, even in TryOptimize. Since we have the flag here now, 
could close() skip the file and persist Skip instead?



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