Slide 1

Slide 1 text

Dynamic で Scalable な 空間分割データ構造 Bkd-Tree 鳥越貴智 2020/11/27 データサイエンス共有会 #meetup_ds

Slide 2

Slide 2 text

Bkd-Tree? 全文検索エンジンElasticsearchで、地理インデックスとして使われている。 BKD-backed geo_shapes in Elasticsearch: precision + efficiency + speed Geospatial Advancements in Elasticsearch Elasticsearchのコアである Apache Luceneで実装されている。 org.apache.lucene.util.bkd

Slide 3

Slide 3 text

Bkd-Tree? kd-Treeの亜種。ざっくり言うとforest of balanced binary kd-trees。 kd-Treeについては「k-d treeによる最近傍探索」が分かりやすい。 K-D-B-Treeよりもディスク使用率が高く追加コストを安くした、という触れ込み のためK-D-B-Treeから紹介します。 ちなみにK-D-B-TreeはWikipediaに英文記事があるものの、Bkd-Treeの解説記事 はほぼ無く「The Bkd Tree: A Dynamic Disk Optimized BSP Tree」くらい。

Slide 4

Slide 4 text

K-D-B-Tree The K-D-B-Tree : a search structure for large multidimensional dynamic indexes (1981)

Slide 5

Slide 5 text

range query を想定 [K-D-B-Tree] Data Structure Region Pages Point Pages 平衡多分木 1 Nodeを 1 Pageに メモリ配置

Slide 6

Slide 6 text

[K-D-B-Tree] Insertions 1. 木を辿って、Pointの位置を含むPoint Pageを探し、Pointを追加する。 2. Pointが増えてPoint Pageが溢れたら、Regionを分割する。 3. Regionが増えてRegion Pageが溢れたら、さらに親のRegionを分割する。 親Regionの分割は、 子Regionの分割を引き起こすため、 コストが高い。

Slide 7

Slide 7 text

[K-D-B-Tree] Splitting Patterns ] Pointの分布特性を知っているならば、 Cyclic以外の分割パターンの方がいい場合もある。

Slide 8

Slide 8 text

[K-D-B-Tree] Deletions and Reorganization 1. Pointが属するPoint Pageから、Pointを削除する。 2. ストレージ使用率が減ってきたらリバランス。 (リバランス例) Region Page A, B, Cの使用率が半分を切ったため、 どれか二つを合体させたいが、 長方形にするためには三つ合体させないといけない。 しかし三つ合体すると溢れるため、 二つの長方形に再分割を行う必要がある。

Slide 9

Slide 9 text

[K-D-B-Tree] Utilization 空のK-D-B Treeに 一様乱数で発生させた100,000Points をCyclicに分割してInsertした実験

Slide 10

Slide 10 text

Bkd-Tree Bkd-Tree: A Dynamic Scalable kd-Tree (2003)

Slide 11

Slide 11 text

[Bkd-Tree] Main Idea ● K-D-B-Treeは追加削除時にリバランスすることでクエリ性能を保つ代わり、 ストレージ使用率が低下する。(その後に提案されたhB-Treeも同じ) ● Bkd-Treeはリバランスせず、後述の「Bulk Load」「Logarithmic Method」 という手法によって、ストレージをほぼ100%で使いきる。 // Bkd-Treeの論文はPageではなくBlockで使用率を考えている。K-D-B-Treeも 1 Node 1 Pageに拘らなければ、キャッシュヒット落とさず使用率上げる 実装はできる気がするものの、これは現代の感覚か(?) // 使用率は置いておいても、枝の数がまちまちだとクエリ性能落ちるので、 できるだけ木をコンパクトにするのは重要なはず。

Slide 12

Slide 12 text

[Bkd-Tree] Bulk Load ● Bkd-Treeは2分木 ○ 葉は一定数のPointを保持する。 ○ 葉のインデックスのシフト演算で、子 ノードのポインタを置き換えられる。 ● 空の木に1点ずつ追加するのではなく、ま とめて木を構築する。 (not Dynamic) ● 1階層ごとにソートして分割位置を決める のではなく、グリッド行列で一気に掘る。

Slide 13

Slide 13 text

[Bkd-Tree] Logarithmic Method ● サイズが指数的に膨らんでいく木の列をなす。ただし列は欠けてもよい。 ● クエリは並列的に投げる。 ● Point追加は、メモリ上のバッファ木  に対して行う。 ○ これはリバランスせず、Leafを大きくしたり深くしたりするはず。 ● バッファ木が溢れたら、ストレージ上の木とBulk Loadによってマージ。 ○ 下図の場合     をマージして、 size 4Mの  を作り出し、   を空にする。

Slide 14

Slide 14 text

[Bkd-Tree] Insertion Performance ● Bkd-Treeは、追加コストがK-B-D-Treeより2桁安い。 ○ 木のマージ自体はコスト高いが、その間もクエリは投げられる。