Skip Graph の concurrent JOIN を考える - その1

id:kibayos さんの PDF「構造化オーバレイの一貫性保証」 に書かれている Skip Graph の一貫性保証の例を読み解く。
http://live-e.naist.jp/sensor_overlay/3/doc/yoshida.pdf (PDF)

探索処理は任意のタイミングで実行可能

資料 P14 。

  • Join は下位レベルから上位へ
  • Remove は上位レベルから下位へ

なので上位から下位に検索する処理には影響がないとの事。


直感的に理解できなかったので具体例を考える。
各レベルでの処理は atomic であると仮定する。
以下のような初期状態の Skip Graph に対して [10] をスタートに key = [9] で検索。

level1: [5]<->[15]  [7]<->[10]
level0: [5]<->[7]<->[10]<->[15]

この状態では検索結果はない。


key = [9] が Join の途中でレベル 0 にのみに Join された以下の状態のとき。
検索結果はないが、「他の検索には一切影響がない」。

level1: [5]<->[15]  [7]<->[10]
level0: [5]<->[7]<->[9]<->[10]<->[15]


つづいて Remove 。上位レベルだけで [7] が Remove された状態。

level1: [5]<->[15]  [10]
level0: [5]<->[7]<->[10]<->[15]

問題なく検索できる。


各レベルでの操作が atomic であれば検索には影響ないことが理解できた。

レベル単位の処理を atomic にできる

資料 P14 。
前提は「一貫性保証のために、処理を小さく分けたい」というモチベーション。この場合「 atomic にできる」とは、同一 key の別レベルの操作も atomic にする必要がないという意味だと思う。
Join / Remove ともに

  1. リンク更新のための情報取得(Buddy は誰?とか)
  2. 各レベルでリンク更新

という順序で行われる。

Remove はレベル単位の処理を atomic にできる?

資料には「自明」とある。考えてみよう。
Remove は上位レベルからスタートし、各レベルで左右のリンクを切って Graph から離脱する。
各レベルでの処理は「そのレベルの左右のノードしか参照しない」という特徴がある。つまり別レベルでの処理に依存しないので atomic にできる。

Join はレベル単位の処理を atomic にできる?

資料には「addKeyの場合は、挿入ポイントを下位レベルの処理後に決定(調整)することで可能になる」とある。
これはつまり、Skip Graph の Join アルゴリズムそのままで、下位の Join が終わってから、下位の buddy を探す方法を指しているのだと思う。


まずは単純な例。 level0 に [9] が Join された状態。level1 の Join は level 0 を参照して正しく行われる。

level1: [5]<->[15]  [7]<->[10]
level0: [5]<->[7]<->[9]<->[10]<->[15]


次に [9] が level0 に Join 後、level1 に Join されるまえに [10] が削除された場合。

level1: [5]<->[15]  [7]<->[10]
level0: [5]<->[7]<->[9]<->[15]

level1 の Join 時には、level0 の buddy が検索されるのだが、正しい buddy [5] が見つけられるので OK 。


その2 に続く。