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
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.
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.
"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
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
Grazie per aver messo questo Ray dritto. Stavo citando: http://java.dzone.com/articles/google-guava-cache –
Finché si sta parlando di Cache
e non di LoadingCache
è possibile passare la vista Cache.asMap()
a Multimaps.newMultimap
.
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
Come gestisci la multimap in continua crescita? – neu242
@ 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