2012-03-05 27 views
11

Esiste una combinazione delle funzionalità di Guava Cache e Multimap? Essenzialmente, ho bisogno di una raccolta in cui le voci scadano dopo un determinato periodo, come disponibile in Cache, ma ho le chiavi non univoche e ho bisogno che le voci scadano in modo indipendente.Combinazione Java guava di Multimap e Cache

risposta

4

Penso che Louis Wasserman abbia fornito la risposta in uno dei commenti sopra, cioè che non è disponibile una combinazione standard di Multimap e Cache. Ho risolto il mio problema/esigenze con la soluzione descritta in pseudo-codice qui sotto:

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

Questa semplice 'soluzione' ha alcune limitazioni ma funziona bene per me.

+1

Come gestisci la multimap in continua crescita? – neu242

+1

@ neu242 per la parte 'SomeConfig' nella risposta corrente è possibile aggiungere una chiamata' .removalListener' lì, che verrà chiamata ogni volta che qualcosa viene rimosso dalla cache, in modo da poterlo rimuovere anche dalla multimap – Philipp

0

Con una cache Guava non esiste il metodo put, la cache è progettata per essere auto-compilante. I valori restituiti da una ricerca chiave vengono calcolati in fase di runtime. Un approccio simile è preso da Commons Collections Transformer Factories.

Penso che si possa implementare facilmente ciò che si sta cercando. Se si osserva un semplice esempio con mappa supportata come Kitty-Cache, è possibile vedere che è possibile sostituire la mappa con una multimappa e riscrivere di conseguenza gli altri metodi. Quindi, in KittyCache.java internamente si potrebbe avere qualcosa di simile:

Multimap<K, CacheEntry<V>> cache; 

Il trucco per questo tipo di cache è che niente scade davvero fino a quando qualcuno lo richiede.

+3

"Con una cache Guava non esiste un metodo put, la cache è progettata per essere auto-compilante" - questo non è vero. È vero che 'Cache' stessa non ha alcun metodo" put "e che' LoadingCache' è progettato per essere auto-compilante, ma puoi sempre usare una cache senza carico e chiamare 'cache.asMap(). Put (.. .) 'per aggiungere le proprie voci. Certo, questo non ti dà un multimap. Correggendo la prima affermazione. – Ray

+2

Dato che Guava 11.0 esiste un [metodo put] (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/Cache.html#put (K, V)) in 'cache'. L'esempio che hai fornito è interessante ma non posso fare affidamento sulla scadenza delle richieste, implemento 'RemovalListener' per ottenere notifiche sulle scadenze in' Cache'. – hgus1294

+1

Grazie per aver messo questo Ray dritto. Stavo citando: http://java.dzone.com/articles/google-guava-cache –

0

Finché si sta parlando di Cache e non di LoadingCache è possibile passare la vista Cache.asMap() a Multimaps.newMultimap.

+0

Interessante. Ho fatto alcuni test ma non riesco a far scadere le voci in modo indipendente. Ho passato un 'Cache.asMap()' in un 'Multimaps.newMultimap' secondo il tuo suggerimento e ha effettuato alcuni test rapidi con 'expireAfterWrite' impostato su 1000 ms ed eseguito il seguente scenario: ' map.put (1, Object1); '' Thread.Sleep (700) '' map.put (1, Object2); '' Thread.Sleep (500) '. A questo punto mi aspetto che la prima voce venga sfrattata, ma la seconda rimanga, ma trovo che entrambe le voci siano sfrattate. Forse sto facendo qualcosa di sbagliato ma a meno che non possa cambiare il comportamento, non funziona per me. – hgus1294

Problemi correlati