2012-03-05 19 views
11

Guava'nın Cache ve Multimap işlevselliğinin bir kombinasyonu var mı? Esasen, girdilerin Cache gibi belirli bir süreden sonra süresinin dolduğu bir koleksiyona ihtiyacım var, ancak benzersiz olmayan anahtarlara sahibim ve bağımsız olarak sürecek kayıtlara ihtiyacım var.Java Guava Multimap ve Cache kombinasyonu

cevap

4

Bence Louis Wasserman cevabını yukarıdaki yorumlardan birinde sağladı, yani Multimap ve Cache 'dan temin edilemeyen bir combo yok. Aşağıda sözde kod özetlenen çözüm ile benim sorunum/gereksinimlerini çözmüş:

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; 
} 

Bu basit 'çözüm' bazı sınırlamaları vardır ama bende çalıştı.

+1

Sürekli büyüyen multimap ile nasıl başa çıkıyorsunuz? – neu242

+1

@ neu242 'SomeConfig' bölümü için geçerli cevapta bir '.removalListener' çağrısı ekleyebilirsin, bu da önbellekten bir şey tahliye edildiğinde çağrılacak, böylece multimaptan da kaldırabilirsiniz – Philipp

0

Guava Önbellekle birlikte yöntemini kullanmayın, önbellek kendi kendine doldurma için tasarlanmıştır. Anahtar aramadan döndürülen değerler çalışma zamanında hesaplanır. Benzer bir yaklaşım Commons Koleksiyonlar Trafo Fabrikaları tarafından alınır.

Aradığınızı kolayca uygulayabileceğinizi düşünüyorum. Kitty-Cache gibi basit bir Harita destekli örneğe bakarsanız, Haritanın Multimap ile değiştirilebileceğini ve diğer yöntemleri buna göre yeniden yazabileceğinizi görebilirsiniz. içten gibi bir şey olabilir KittyCache.java Yani:

Multimap<K, CacheEntry<V>> cache; 

cache bu tür hile birisi istekte hiçbir şey gerçekten sona olmasıdır.

+3

"Bir Guava Önbelleği ile bir kılma yöntemi yoktur, önbellek kendi kendini popüle edecek şekilde tasarlanmıştır" - bu doğru değildir. 'Önbellek' kendisinin hiçbir yöntemi yoktur 'koyma' ve 'LoadingCache' kendi kendini doldurmak için tasarlanmıştır, ancak her zaman yükleme olmayan bir önbellek kullanabilirsiniz ve 'cache.asMap(). .) 'kendi girişlerinizi eklemek için. Tabii ki, bu size bir multimap almaz. Sadece ilk ifadeyi düzeltmek. – Ray

+2

Guava 11.0'dan beri bir [put yöntemi] var (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/Cache.html#put (K, V)) 'Cache'. Sağladığınız örnek ilginç ancak isteklerin süresinin dolmasına dayanamıyorum, 'Önbellek' ifadesindeki doluluklarla ilgili bildirim almak için 'RemovalListener 'dosyalarını kullanıyorum. – hgus1294

+1

Bu düz Ray'ı seçtiğiniz için teşekkürler. Alıntı yaptım: http://java.dzone.com/articles/google-guava-cache –

0

Cache ve LoadingCache'dan bahsederken, Cache.asMap() görünümünü Multimaps.newMultimap içine geçirebilirsiniz.

+0

İlginç. Bazı testler yaptım ama girişlerin bağımsız olarak süresinin dolmasını sağlayamıyorum. Bir 'Cache.asMap()' bir 'Multimaps 'içine geçirdi.newMultimap' önerinize göre ve 'expireAfterWrite' ile 1000 ms'ye ayarlanmış ve aşağıdaki senaryoyu çalıştıran bazı hızlı testler yaptı: ' map.put (1, Object1); '' Thread.Sleep (700) '' map.put (1, Object2); 'Thread.Sleep (500)'. Bu noktada ilk tahliyenin tahliye edilmesini bekliyorum, ancak ikincisi kalacak ama her iki girişi de tahliye edeceğim. Belki yanlış bir şey yapıyorum ama davranışı değiştiremezsem, benim için işe yaramıyor. – hgus1294