0
0
Fork
You've already forked comaps
0
forked from comaps/comaps

[search] Use ICU for CJK word break #9

Open
eisa01 wants to merge 1 commit from icu-cjk-fix into main
pull from: icu-cjk-fix
merge into: eisa01:main
eisa01:main
eisa01:eisa01/carplay-road-shields
eisa01:multi-surface-map-rendering
eisa01:carplay-dashboard-support
eisa01:modes-ui
eisa01:carplay-0708
eisa01:forgejo-macos-runner
eisa01:create-venv
eisa01:carplay-0706
eisa01:carplay-0704-findings
eisa01:fable-review
eisa01:testflight/2026.06.30
eisa01:carplay-dashboard
eisa01:carplay-om-code-review
eisa01:carplay-code-review-jun28
eisa01:carplay-dashboard-mvp2
eisa01:car-follow-on-reacquire
eisa01:carplay-location-keepalive
eisa01:testflight/2026.06.20
eisa01:carplay-roundabout-exit-number
eisa01:carplay-destination
eisa01:carplay-dashboard-mvp
eisa01:name-cherry-picking
eisa01:om-pr-11243-2
eisa01:simple-cjk-fix
eisa01:fix-crash-search
eisa01:scene-support
eisa01:om-carplay-button
eisa01:om-pr-10545
eisa01:submodule-main-branch
eisa01:improve-unit-testing-docs

Done fully by Claude Opus 4.6. Had lots of trouble compiling the new .dat file, but managed to debug it

Summary

  • Enable ICU BreakIterator with CJK dictionary support to fix search for partial Chinese/Japanese/Korean place names (issue #3835)
  • Searching "博物館" now finds "國立臺灣博物館"; searching "博物" does not — correct word-level precision

Changes

ICU build system

  • 3party/icu/uconfig_local.h: Removed UCONFIG_NO_BREAK_ITERATION and UCONFIG_NO_FILTERED_BREAK_ITERATION
  • 3party/icu/CMakeLists.txt: Added 13 break iterator source files to icuuc (rbbi*.cpp, brkiter.cpp, ubrk.cpp, dictbe.cpp, dictionarydata.cpp)
  • 3party/icu/icu_filter.json: Added brkitr_rules and brkitr_dictionaries features

ICU data

  • data/icudt75l.dat: Rebuilt with break iterator rules and CJK dictionary — grows from 1.3 MB to 4.5 MB. New contents include word.brk, cjdict.dict (Chinese/Japanese word list, BSD-licensed via Chromium/Libtabe/IPADIC), and the full set of break rules.

Search tokenization

  • libs/indexer/search_string_utils.hpp: Added IsCJKChar() range check and SegmentCJKWords() declaration; modified SplitUniString to detect CJK runs and delegate to SegmentCJKWords instead of treating them as a single token
  • libs/indexer/search_string_utils.cpp: Implemented SegmentCJKWords() using icu::BreakIterator::createWordInstance("zh"), which activates the CJK dictionary for word-boundary detection; falls back to per-character tokenization if ICU data is unavailable

Tests

  • libs/search/search_integration_tests/processor_test.cpp: Added ChinesePOISearchTest covering full-name, suffix-word, and multi-word queries against a Chinese POI

How to rebuild icudt75l.dat

The data rebuild requires a bootstrap step (ICU tools need Unicode property data to compile break rules):

cd 3party/icu && mkdir -p build && cd build
ICU_DATA_FILTER_FILE=../icu_filter.json \
 ../icu/icu4c/source/configure --disable-shared --enable-static \
 --disable-renaming --disable-extras --disable-icuio \
 --disable-tests --disable-samples --with-data-packaging=archive
make -j$(nproc)
# Bootstrap before running make (needed once per clean build):
cd data
DYLD_LIBRARY_PATH=../lib:../stubdata:../tools/ctestfw:$DYLD_LIBRARY_PATH \
 ../bin/gencnval -d ./out/build/icudt75l \
 -s ../../icu/icu4c/source/data/mappings convrtrs.txt
cp ../../icu/icu4c/source/data/in/*.icu \
 ../../icu/icu4c/source/data/in/*.nrm \
 ./out/build/icudt75l/
make -j$(nproc)
cp out/icudt75l.dat ../../../../data/
Done fully by Claude Opus 4.6. Had lots of trouble compiling the new .dat file, but managed to debug it > ## Summary > > - Enable ICU `BreakIterator` with CJK dictionary support to fix search for partial Chinese/Japanese/Korean place names (issue #3835) > - Searching "博物館" now finds "國立臺灣博物館"; searching "博物" does not — correct word-level precision > > ## Changes > > ### ICU build system > - **`3party/icu/uconfig_local.h`**: Removed `UCONFIG_NO_BREAK_ITERATION` and `UCONFIG_NO_FILTERED_BREAK_ITERATION` > - **`3party/icu/CMakeLists.txt`**: Added 13 break iterator source files to `icuuc` (`rbbi*.cpp`, `brkiter.cpp`, `ubrk.cpp`, `dictbe.cpp`, `dictionarydata.cpp`) > - **`3party/icu/icu_filter.json`**: Added `brkitr_rules` and `brkitr_dictionaries` features > > ### ICU data > - **`data/icudt75l.dat`**: Rebuilt with break iterator rules and CJK dictionary — grows from 1.3 MB to 4.5 MB. New contents include `word.brk`, `cjdict.dict` (Chinese/Japanese word list, BSD-licensed via Chromium/Libtabe/IPADIC), and the full set of break rules. > > ### Search tokenization > - **`libs/indexer/search_string_utils.hpp`**: Added `IsCJKChar()` range check and `SegmentCJKWords()` declaration; modified `SplitUniString` to detect CJK runs and delegate to `SegmentCJKWords` instead of treating them as a single token > - **`libs/indexer/search_string_utils.cpp`**: Implemented `SegmentCJKWords()` using `icu::BreakIterator::createWordInstance("zh")`, which activates the CJK dictionary for word-boundary detection; falls back to per-character tokenization if ICU data is unavailable > > ### Tests > - **`libs/search/search_integration_tests/processor_test.cpp`**: Added `ChinesePOISearchTest` covering full-name, suffix-word, and multi-word queries against a Chinese POI > > ## How to rebuild `icudt75l.dat` > > The data rebuild requires a bootstrap step (ICU tools need Unicode property data to compile break rules): > > ```bash > cd 3party/icu && mkdir -p build && cd build > ICU_DATA_FILTER_FILE=../icu_filter.json \ > ../icu/icu4c/source/configure --disable-shared --enable-static \ > --disable-renaming --disable-extras --disable-icuio \ > --disable-tests --disable-samples --with-data-packaging=archive > make -j$(nproc) > > # Bootstrap before running make (needed once per clean build): > cd data > DYLD_LIBRARY_PATH=../lib:../stubdata:../tools/ctestfw:$DYLD_LIBRARY_PATH \ > ../bin/gencnval -d ./out/build/icudt75l \ > -s ../../icu/icu4c/source/data/mappings convrtrs.txt > cp ../../icu/icu4c/source/data/in/*.icu \ > ../../icu/icu4c/source/data/in/*.nrm \ > ./out/build/icudt75l/ > make -j$(nproc) > cp out/icudt75l.dat ../../../../data/ >
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin icu-cjk-fix:icu-cjk-fix
git switch icu-cjk-fix

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff icu-cjk-fix
git switch icu-cjk-fix
git rebase main
git switch main
git merge --ff-only icu-cjk-fix
git switch icu-cjk-fix
git rebase main
git switch main
git merge --no-ff icu-cjk-fix
git switch main
git merge --squash icu-cjk-fix
git switch main
git merge --ff-only icu-cjk-fix
git switch main
git merge icu-cjk-fix
git push origin main
Sign in to join this conversation.
No reviewers
Labels
Clear labels
No items
No labels
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
eisa01/comaps!9
Reference in a new issue
eisa01/comaps
No description provided.
Delete branch "icu-cjk-fix"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?