2012-03-05 16 views
11

GuavaのCacheMultimapの機能を組み合わせて使用​​できますか?基本的には、Cacheなどで指定した時間が経過してエントリが期限切れになるコレクションが必要ですが、一意でないキーがあり、エントリを個別に期限切れにする必要があります。マルチマップとキャッシュのJava Guavaの組み合わせ

答えて

4

Louis Wassermanは、上記のコメントの1つで、MultimapCacheという市販のコンボはありません。私は、以下の擬似コードで概説した溶液で私の問題/要件を解決した:

private Cache<Integer,Object> cache = CacheBuilder.newBuilder().SomeConfig.build(); 
private Multimap<Integer,Object> multimap = HashMultimap<Integer, Object>.create(); 
private AtomicInteger atomicid = new AtomicInteger(0); 

public void putInMultimap(int id, Object obj) { 
    int mapid = atomicid.addAndGet(1); 
    cache.put(mapid,obj); 
    multimap.put(id,mapid); 
} 
public List<Object> getFromMultimap(int id) { 
    Set<Integer> mapids = multimap.get(id); 
    List<Object> list = new ArrayList<Object>(); 
    for (int i : mapids) { 
     list.add(cache.getIfPresent(i)); 
    } 
    return list; 
} 

この単純な「解決策」は、いくつかの制限がありますが、それは私のために[OK]を動作します。

+1

絶え間なく成長しているマルチマップをどのように処理しますか? – neu242

+1

@ neu242現在の回答の 'SomeConfig'部分では、そこに' .removalListener'呼び出しを追加することができます。これは、何かがキャッシュから追い出されるときに呼び出されるので、マルチマップから削除することもできます – Philipp

0

Guavaキャッシュにはputメソッドがありません。キャッシュは自己生成型に設計されています。キー参照から返される値は、実行時に計算されます。同様のアプローチはCommons Collections Transformer Factoriesによって行われます。

あなたはあなたが探しているものを簡単に実装できると思います。 Kitty-Cacheのような単純なMapバッキングの例を見ると、MapをMultimapに置き換えて、それに応じて他のメソッドを書き換えることができます。内部的にあなたのようなものを持っている可能性がKittyCache.java中のSO:

Multimap<K, CacheEntry<V>> cache; 

キャッシュこの種のトリックは、誰かがそれを要求するまで何が本当に有効期限が切れていないということです。

+3

"Guavaキャッシュではputメソッドがなく、キャッシュは自己生成型になるように設計されています" - これは当てはまりません。実際には 'Cache'自体には' put 'メソッドがなく、 'LoadingCache'は自己生成型であるように設計されていますが、ロードされていないキャッシュを使用し、' cache.asMap()。put(.. 。) 'あなた自身のエントリーを追加する。もちろん、これはマルチマップを取得しません。最初のステートメントを修正するだけです。 – Ray

+2

Guava 11.0以降、[putメソッド](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/Cache.html#put(K、V))が'キャッシュ'。あなたが提供した例は興味深いですが、私は要求の期限に頼ることができません。私は、 'RemovalListener'を実装して' Cache'の期限切れを通知します。 – hgus1294

+1

このストレートレイを入れてくれてありがとう。私は引用していました:http://java.dzone.com/articles/google-guava-cache –

0

Cacheで、LoadingCacheでない限り、Cache.asMap()Multimaps.newMultimapに渡すことができます。

+0

興味深い。私はいくつかのテストをしましたが、エントリを個別に期限切れにすることはできません。私は 'Cache.asMap()'を 'Multimaps 'に渡しました。newMultimap'をあなたの提案にしたがって実行し、 'expireAfterWrite'を1000ミリ秒に設定していくつかの簡単なテストを行い、以下のシナリオを実行しました: ' map.put(1、Object1); '' Thread.Sleep(700) '' map.put (1、Object2); '' Thread.Sleep(500) 'となります。この時点で、私は最初のエントリが追い出されることを期待していますが、2番目のエントリは残っていますが、両方のエントリが追い出されることがわかります。たぶん私は間違ったことをやっているのですが、私がその行動を変えなければ、それは私のためには機能しません。 – hgus1294

関連する問題