2016-07-11 6 views
1

私はBerkeley DBでの比較とスワップ操作を効率的に実装する方法を探しています。今は本当に古いバージョンを使用していますが、一見して最新のもの(Oracle Webサイトから配布されているもの)でさえ、そのような操作のための単一の方法はありません。Berkeley DB JEの比較とスワップ?

私は、以下の意味を持つ

replace(Transaction, Key, ExpectedValue, NewValue) 

のような方法のいくつかの種類を探していた

:DBは、与えられたキーに関連付けられた値を取得し、この値が存在し、それが期待値と等しい場合、この値は次のようになりますNewValueに変更されます。そうでない場合、メソッドは、失敗したOperationStatusを返します。

このような方法がないように見えるので、これが最も効率的な方法でどのように行われるのだろうと思います。

今私は、次のアプローチを使用しています:私は、彼らが私は古いバージョンを消去し、最終的な更新を行う一致する場合、私は、値とバージョンを比較

db.get(null, key) -> {currentValue, version} 
db.put(null, key, {currentValue, newRandomIdVersion}) 
db.get(null, key) 

を行います。ステップが失敗すると、プロセス全体が再開します。

私はこれが非常に最適ではないと感じます - 私は間違っていますか?

+0

試しましたか? –

+0

最初の亀裂として、トランザクションを使用して、パフォーマンスが十分な規模であるかどうかを確認してください。 –

+0

トランザクション内のカウンターを更新するだけですか?それは助けにならないでしょう - 並行トランザクションはそれ自身をオーバーライドします。 – Alex

答えて

0

私の質問への私の解決策は間違っていますが、改善のためにわずかな変更が必要です。

解決策は次のようなものです:いくつかのカウンタへのキーの関連を保持するロックを格納するための別個のDBを作成する。このDBは、ソートされた重複を許可する必要があります(Database.getは、指定されたキーに関連付けられた最小値を返すようになります)。その後、共有単調増加カウンタを使用します。 CASを実行しようとする複数のスレッドは、このカウンタから値を取得し、そのロックDBにキーと値のペアを格納します。スレッドには、キーに関連付けられた最低値が格納され、書き込み権限があるものとみなされ、目的のレコードの比較とスワップを行い、ロックDBからエントリを削除します。

関連する問題