airborne12 opened a new pull request, #70261:
URL: https://github.com/apache/doris/pull/70261

   > Stacked PR in the SNII / text analysis / ANN CLucene removal series (index 
at the end). It depends on #70260 (T1), whose commits show in this diff until 
they merge; review only this PR's own commits: `52719502834` [refactor](be) Add 
the CLucene-free text analysis interface and its two CLucene adapters. It stays 
a draft until its dependencies merge.
   
   ### What problem does this PR solve?
   
   Issue Number: None
   
   Related PR: #70260
   
   Problem Summary:
   
   The SNII text analysis is moving off CLucene. Today every
   consumer (the SNII writer, the query side, the V1/V2 writers) reaches an
   analyzer through lucene::analysis::Analyzer, TokenStream and Token, one 
virtual
   call per token, so no analyzer can leave CLucene before every consumer does,
   and the other way round. This adds the interface both sides move to, with no
   production caller yet, and the two adapters that let consumers and analyzers
   move one at a time.
   
   The interface is in storage/index/inverted/analysis/ and includes no CLucene
   header; the gate adds no exception for it.
   - TokenBatch: the tokens of one next_batch() call, each a term view and a
     position increment. A term points into the value, into memory the stream
     keeps, or into the batch's arena, which never moves a term it handed out.
     clear() keeps the token array and the arena's largest block;
     release_oversized() frees everything once the batch keeps more than 64 KiB,
     so one huge value does not pin its memory until the segment ends.
   - TextTokenStream, with TextTokenizer and TextTokenFilter: reset(text) binds 
a
     value, next_batch() hands out up to 256 tokens and returns false, with an
     empty batch, only at the end, and reserved_bytes() reports what survives a
     value.
   - PerTokenTokenizer and PerTokenFilter: bases for components that make one
     token at a time; the base copies each term into the batch. A filter reads 
its
     input through a private batch, so it may hold an input token across 
batches,
     as word_delimiter holds a token while it hands out its parts.
   - TextAnalyzer: immutable after it is built, shared by threads, makes 
streams.
   The 64 KiB high water mark and release_oversized_scratch() move from
   token_stream.h to a new scratch.h, so the batch uses them without CLucene.
   
   The adapters are in storage/index/inverted/clucene/:
   - LuceneBackedTextAnalyzer puts a CLucene analyzer behind TextAnalyzer, for 
the
     consumers that switch before their analyzers do. Each value gets a new 
reader
     through the index's char filter and a new CLucene stream, as a query reads 
a
     value today (the SNII writer re-initializes one reader instead); terms are
     copied into the batch, and a CLuceneError comes out as a doris::Exception. 
It
     goes once every analyzer is native.
   - LuceneAnalyzerBridge puts a TextAnalyzer behind lucene::analysis::Analyzer,
     for the V1/V2 writers. reusableTokenStream() rebinds one stream per scalar
     value, tokenStream() makes an owned stream per array element, reset() 
starts
     the value as SDocumentsWriter::invertField() expects, and terms go out with
     setTextNoCopy(), empty ones included, because those writers give an empty
     term a position.
   
   One difference turned up and is pinned by a test: on the V1/V2 array path,
   ICUAnalyzer::tokenStream() resets the stream and invertField() resets it
   again, and ICUTokenizer, which reads its reader in reset(), finds it 
consumed:
   array elements of an icu index are indexed as nothing. The bridge starts each
   element once and indexes them. No table can have such an index, because the 
FE
   accepts no parser and no analyzer on an array column
   (InvertedIndexUtil.checkInvertedIndexParser).
   
   ### Release note
   
   None
   
   ### Check List (For Author)
   
   - Test <!-- At least one of them must be included. -->
       - [ ] Regression test
       - [x] Unit Test
       - [ ] Manual test (add detailed scripts or steps below)
       - [ ] No need to test or manual test. Explain why:
           - [ ] This is a refactor/code format and no logic has been changed.
           - [ ] Previous test can cover this change.
           - [ ] No code files have been changed.
           - [ ] Other reason <!-- Add your reason?  -->
   
       Details:
       - ./run-be-ut.sh --run 
--filter='TokenBatchTest.*:PerTokenStreamTest.*:LuceneBackedTextAnalyzerTest.*:LuceneAnalyzerBridgeTest.*:LuceneBridgeWriterTest.*:AnalysisGolden*:AnalysisDifferential*:AnalysisWriteGolden*:AnnWriteGolden*:SniiWriterGoldenBytes*:SniiGoldenCorpus*:InvertedIndexWriterTest.*'
         passes on ASAN, with no leak report.
       - TokenBatchTest: 10000 copied terms over many arena blocks keep their
         bytes; clear() keeps the token array and the largest block, and a batch
         that fits allocates nothing; release_oversized() leaves at most 64 KiB
         after 10000 tokens or a 1 MiB term, and keeps an ordinary batch.
       - PerTokenStreamTest: batches of at most 256 tokens; a filter making two
         tokens out of one; a filter dropping every token returns false, never 
an
         empty batch; a filter holding a 300-character token across two batches;
         next_token() is not called after it returned false; reset() in the 
middle
         of a value does not replay it; reserved_bytes() adds up the chain and
         reset() releases an oversized input batch.
       - expect_text_stream_contract(), a checker later components reuse: false
         only with an empty batch and again after, no token for an empty value 
with
         a null or a non-null pointer, a reused stream equal to a new one, and a
         reset after the first batch. It passes on the test streams, on a 
scripted
         CLucene analyzer and on the standard analyzer through
         LuceneBackedTextAnalyzer.
       - AnalysisGolden.LuceneBackedTextAnalyzerMatchesTheFrozenDigests: all 122
         analyzer configurations through LuceneBackedTextAnalyzer, with a new
         stream per line and with one stream for all lines, match
         analysis_golden.txt (3172 jobs).
       - AnalysisGolden.EightThreadsShareOneTextAnalyzer: eight threads share 
each
         configuration's analyzer on mixed_zh_en and invalid_utf8, half with a 
new
         stream per line, and all match the frozen digests.
       - AnalysisWriteGolden.LuceneAnalyzerBridgeWritesTheSameV2Index: the
         production V2 writer with its analyzer behind the bridge writes the
         frozen string-column digests of chinese, ik, icu and the custom chain,
         and the same array-column index as the analyzer itself, except the icu
         case above.
       - LuceneBridgeWriterTest: a doris::Exception from reset() or next_batch()
         reaches add_values() and add_array_values() as
         INVERTED_INDEX_ANALYZER_ERROR through the CLucene frames.
       - analysis_golden.txt and ann_write_golden.txt unchanged.
         build-support/check-build-hygiene.sh passes with the same 31 + 51
         exceptions. build-support/run-clang-tidy.sh reports no warning on the
         changed lines.
   
   - Behavior changed:
       - [x] No.
       - [ ] Yes.
   
   
   - Does this need documentation?
       - [x] No.
       - [ ] Yes.
   
   ### Check List (For Reviewer who merge this PR)
   
   - [ ] Confirm the release note
   - [ ] Confirm test cases
   - [ ] Confirm document
   - [ ] Add branch pick label
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


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