Writer: numeric dict layout is chosen by a 2,048-distinct cap; Rust probes and writes several dictionaries

オープン
#649 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
28/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
java, rust
領域
data

調査の方向性

Start in DictColumnState.isDictCandidate and the GLOBAL_DICT_MAX_CARDINALITY cap in vortex-java, then compare with DictStrategy in vortex-layout/src/layouts/dict/writer.rs, which probes a sample and writes several dictionaries. Read ADR 0021 before changing the heuristic. Reproduce with Int64NarrowingInteropIntegrationTest using a one-column HASH_CSV dump. Done means the RefererHash tree matches the vortex-jni dict layout and high-cardinality I64/F64 columns show no regressions.

索引モデルが issue の本文から書いたものです。

説明

perf

Raincloud clickbench-hits, vortex-java's Parquet import vs the vortex-jni-written file, data bytes (99.997M rows):

column type Rust Java
RefererHash I64 401.0 MB 791.3 MB (1.97x)
URLHash I64 427.3 MB 790.0 MB (1.85x)

Cause (confirmed)

Not integer narrowing: the values are full 64-bit. Rust writes these columns as a dict layout; Java writes plain vortex.primitive (8 bytes a row).

Reproduced with 131,072 real RefererHash rows (first chunk of ClickBench hits.parquet, ~23k distinct), written by both writers:

file tree
vortex-jni 434 KB vortex.dict layout: vortex.primitive values + fastlanes.bitpacked codes
vortex-java 1,050 KB vortex.primitive

Synthetic i32/u32/i16-range, mixed and full-i64 columns already produce identical trees in both writers, so narrowing is not involved.

  • Rust (vortex-layout/src/layouts/dict/writer.rs, DictStrategy): compresses a probe sample with the cascade; if the result is a Dict, it writes a dict layout, up to u16::MAX values per dictionary, and starts a new dictionary when the constraint is hit.
  • Java (DictColumnState.isDictCandidate): a numeric column is offered a global dict only with at most GLOBAL_DICT_MAX_CARDINALITY (2,048) distinct values and under 50% distinct, one dictionary for the whole column, demoted to per-chunk encoding past the cap. This column has ~23k distinct per chunk and ~719k over 2M rows.

Fix

Raising the cap is not enough: over the whole column Rust writes several dictionaries in sequence. Parity means replacing the cardinality heuristic with Rust's probe-then-multi-dictionary flow (touches ADR 0021, and the comment on the cap says a global dict hurt some high-cardinality I64/F64 columns, so check those for regressions).

Repro: Int64NarrowingInteropIntegrationTest (exploratory, not committed), fed HASH_CSV=<one-column dump>.

主要言語
Java
スター
3
フォーク
2
平均マージ
9時間 47分
マージ済み PR(30日)
128

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

dfa1/vortex-java のほかの issue

dfa1/vortex-java の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。