Skip to content

Build the K-D tree with quickselect instead of sorting at every level - #18

Closed
wf9a5m75 wants to merge 1 commit into
developfrom
perf/marker-spatial-index
Closed

wf9a5m75 wants to merge 1 commit into
developfrom
perf/marker-spatial-index

Conversation

@wf9a5m75

@wf9a5m75 wf9a5m75 commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

MapConductor/js-sdk-core#20 と同じ修正の Android 版。

js-sdk-core#20 との対応

js-sdk-core#20 Android
pointerdown でドラッグ可能なマーカーが無ければ引き当てない 対象外。Android のドラッグ開始は長押しで、タッチのたびに空間インデックスを引かない
HexCellRegistry:セルの集合が変わったときだけ作り直しの印を付ける 実装済み(develop の時点で入っている)
HexCellRegistry:既にあるセルは置き換えない このPR
KDTree:quickselect で構築 このPR

修正

  • KDTree:階層ごとにセルを並べ替えて subList で分けていたのをやめ、1 本の配列の中で中央値だけを選んで(Wirth の quickselect)、添字の範囲で再帰する。六角セルの中心は列ごとに同じ x を持ち、等しい値が大量に並ぶので、左右から寄せる分割にした。渡されたリストは並べ替えない
  • HexCellRegistry.setPoint:既にあるセルは putIfAbsent で置き換えず、返すのもそのセルにする(木が持っているセルと揃える)。同じセルのままの更新でも、登録済みのセルを返す

公開 API の変更は無い。

確認

  • ./gradlew testDebugUnitTest:295 件すべて通る
  • 追加した KDTreeBuildTest
    • nearest / withinRadiusWithDistance / nearestKWithDistance が総当たりと一致する(同じ座標が並ぶ 40×40 の格子・ばらばらの 3,000 点)
    • 渡したリストを並べ替えない
  • 既存の HexCellRegistryRebuildTest(5 件)・KDTreeRadiusTest も通る
  • ktlint:変更したファイルに指摘なし
  • K-D 木の構築(6 万セル、並びをシャッフル、Mac の JVM、10 回平均):21.9 ms → 10.5 ms。実機では測っていない

KDTree sorted a copy of the cells at every level and split it into sublists.
It now selects only the median inside one array (Wirth's quickselect) and
recurses on index ranges. Hex cell centres share x per column, so the
partition closes in from both ends; a one-sided partition is O(n^2) on
equal keys. The caller's list is not reordered.

HexCellRegistry.setPoint no longer replaces a cell that is already
registered, so the cell it returns is the one the tree holds. Only marking
the tree dirty when the set of cells changes was already in place here.

Same change as MapConductor/js-sdk-core#20.
@wf9a5m75

wf9a5m75 commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

K-D 木は 928e7c3 で MarkerGridIndex に置き換え済みで、HexCellRegistry/KDTree はマーカー検索で使われていないため、この最適化は不要。K-D 木そのものの削除は別 PR で行う。

@wf9a5m75 wf9a5m75 closed this Nov 5, 2026
@wf9a5m75
wf9a5m75 deleted the perf/marker-spatial-index branch November 5, 2026 02:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant