16

プライマリとセカンダリの 2​​ 種類のインデックスがある単純化されたインメモリ キャッシュ "テーブル" を実装しようとしています。

  • プライマリ インデックスは、単一のキー (プライマリ キー) を一意の値にマップします (マップ インターフェイス)

  • セカンダリ インデックスは、単一のキーを値のコレクションにマップします (マルチマップは請求書に適合します)。

いくつかのルックアップ列を持つ RDBMS の世界のテーブルに非常に似ています。PK で検索したい場合もあれば、共通のプロパティに基づいて行のリストを返す場合もあります。現在、等号 (=) 以外の演算は必要ありません (つまり、範囲クエリやパターン マッチングは必要ありません)。

上記のデータ構造にキャッシュ セマンティクスを追加します (エビクション、データ生成/キャッシュ ローダー、更新など)。

与えられた問題への最善のアプローチ方法についてアドバイスをお願いしたいと思います。インデックスごとのキャッシュまたはキャッシュ (PK の場合) + (同期された) セカンダリ インデックスのマルチマップである必要がありますか?

どんな助けでも大歓迎です。

よろしく。

4

3 に答える 3

2

Map を Guava com.google.common.cache.Cache に置き換えることができます。Multimap タイプのセマンティクスをサポートしていないため、使用する必要があります

Cache<K, ? extends List<V>> 

その場合。

簡単にするために、「プライマリ インデックス」をセカンダリ インデックスのサブセットにします。つまり、特定のキーの値のリストを返す単一のインデックスがあり、プライマリ キーは単一の値を持つリストを返すだけです。

于 2012-06-07T14:53:38.607 に答える
1

ここでの課題は、PK +マルチマップに2つのキャッシュを使用するか、1つのキャッシュを使用するかに関係なく、2つのインデックスの整合性を維持することです。

com.google.common.cache.Cacheを拡張する新しいキャッシュクラス(TableCacheなど)を作成する必要があるかもしれません。このクラスは、セカンダリインデックス(ConcurrentHashMapの場合もあります)のマルチマップインスタンス変数を内部的に維持できます。

次に、キャッシュメソッド(put、get、invalidateなど)をオーバーライドして、セカンダリインデックスの同期を維持できます。

もちろん、セカンダリインデックスに基づいて値を取得するためのget関数を提供する必要があります。

このアプローチにより、プライマリインデックスとセカンダリインデックスの整合性を維持できます。

public class TableCache<K, V> extends Cache<K, V> {

    Map<K, List<V>> secondaryIndex = new ConcurrentHashMap<K, List<V>>();

    public void put(K key, V value) {
        super.put(key, value);
        // Update secondaryIndex
    }

}
于 2012-06-13T20:11:30.067 に答える
0

私はこの問題を何度も経験しました。

Java のSTM サポートが改善されれば、この問題は解決します。非ブロッキングのアトミック データ構造を作成することは非常に困難です。私が見た中で最高のものはmultiverseです。

したがって、@ vladimirの答えはおそらく最良ですが、保存されたコレクションは不変である必要があり、リフレッシュ/キャッシュミスなどでコレクション全体を取得する必要があると思います....また、マルチセットのメンバーの1つを変更すると、親を更新してキャッシュを無効にする方法を知るのに苦労する.

それ以外の場合は、マップとリストの組み合わせでのアトミック操作をサポートする、より大きなデータ セット用のRedisのようなものを検討します。

于 2012-10-17T12:26:05.557 に答える