![](https://s.togetter.com/static/web/img/placeholder.gif)
コンストラクタでパラメータを受け取る場合とか「あぁこうやって使わせるのかー」というのがすごく勉強になる。このlevelDBの作者はRubyの環境に慣れ親しんでるのではなかろうか。
2011-05-17 20:48:36![](https://s.togetter.com/static/web/img/placeholder.gif)
Getはlockを取らないので衝突しないし、WriteとGetも衝突しない。衝突するのはWrite同士。Write処理ついでにコンパクションするとなると衝突時の調停が面倒になり過ぎるしスケールさせる必要もない、と。
2011-05-17 21:38:56![](https://s.togetter.com/static/web/img/placeholder.gif)
んー。なるほどー、insert処理がシングルスレッドで排他としてしまった途端にアロケータも密結合にできるし削除の心配もしなくていい、と。メモリの寿命管理に思い切った判断がいくつも入っていて勉強になる。
2011-05-17 22:15:56![](https://s.togetter.com/static/web/img/placeholder.gif)
dbのwrite()に対してバッチ(処理を詰め込んだ構造体)を渡してやるとその中でwriteのlockをとって複数回skiplistに書き込める。readが一貫性のない状態を読みだしちゃう事に関しては気にしてなさげ。
2011-05-17 22:17:38![](https://s.togetter.com/static/web/img/placeholder.gif)
batch構造体の中のsliceは呼び出し元が所有している。そこで呼び出すmemtable.ccでのadd()の中でアロケートしたバッファにmemcpyして、そこへのポインタをSkipListにinsertしてる。ポインタを保持するSkipListだけどコンパレータは文字列比較。
2011-05-17 22:47:42![](https://s.togetter.com/static/web/img/placeholder.gif)
LevelDB自体はファイルベースのKVSであることと,level with skiplistによる検索などが分かるとほとんどわかったも同然なはず!memtableとかはあれだし…
2011-05-17 22:54:53![](https://s.togetter.com/static/web/img/placeholder.gif)
@repeatedly コンパレータの実装がどこにあるのか分からないんですけれどもどういう順序付をするコンパレータなんでしょうか?
2011-05-17 22:58:41![](https://s.togetter.com/static/web/img/placeholder.gif)
@kumagi_bot InternalKeyComparatorは今のところBytewiseComparatorくらいしかまともに使ってなさげ
2011-05-17 23:29:53![](https://s.togetter.com/static/web/img/placeholder.gif)
BytewiseComparatorは普通にSliceのcompare読んでるだけか.Findなんちゃらは何やってんだろ?
2011-05-17 23:32:42![](https://s.togetter.com/static/web/img/placeholder.gif)
LevelDBのSkipList::Iteratorはやっぱりロックを取らずにイテレートできるようにはなってるけど、Insertがlock-freeな感じの実装になってない上にロックも取ってないんだけどどういうことなんだろう。read/writeが同時に発生しないようにしてる?
2011-05-17 23:29:02![](https://s.togetter.com/static/web/img/placeholder.gif)
dbformat.ccの38行目のところのInternalKeyComarator::Compareが本体だろうか。けっけよく内部でCompare呼んでるんだが、こうもCompareの中でCompare呼ばれるとどこかで再帰しないのか不思議でしょうがない。
2011-05-17 23:29:25![](https://s.togetter.com/static/web/img/placeholder.gif)
想定としてはMRSWな感じなのかな。だとしたらAtomicPointer使ってるのは何で。SWだとこの実装で大丈夫なのかな。
2011-05-17 23:30:00![](https://s.togetter.com/static/web/img/placeholder.gif)
@nobu_k insertのロック処理はDBImplのWriteの中で取ってます。バッチ的に複数書きこむ事がメインの用途なので、SkipList側でロックとっても意味がないという判断のようです。Arenaアロケータもシングルスレッド用ですね。
2011-05-17 23:33:10![](https://s.togetter.com/static/web/img/placeholder.gif)
@nobu_k SWなのにAtomicPointer使ってるのはリーダとライターが衝突した際に、コンストラクトが不完全なNodeを間違ってもリーダが参照しないようにバリアしてるんですね。レベル0だけ守れば良いんですけれどちょっと過保護っぽい印象。
2011-05-17 23:38:43![](https://s.togetter.com/static/web/img/placeholder.gif)
@nobu_k SkipList.hの363周りのコメントに書いてあるメモと、そのちょっと上のNewNodeが追い越してない事を明示させたいんだと思いますけれど、x86アーキテクチャに限ってはこの手のバリアは不要だという判断です。コンパイル時に消えるかと。
2011-05-17 23:43:19![](https://s.togetter.com/static/web/img/placeholder.gif)
@kumagi なんかそもそもmemory_order_relaxedで読み込んでるのであんまりバリアに期待してなさそうな感じで、良くわからんです。生ポインタ経由よりもatomic経由で明示的にmemory_order_relaxedを指定した方がC++0xだと速いとかあるのかな
2011-05-17 23:49:04