2011-07-27 1 views
9

Szukam informacji o pamięci podręcznej na mapie, więc nie muszę przechowywać, na przykład, trafienia do bazy danych. W Javie korzystałem z doskonałej kolekcji Google MapMaker i ustawiłem termin wygaśnięcia, aby zachować pamięć podręczną tak świeżą, jak to konieczne oraz wartości miękkie, aby zmniejszyć zużycie pamięci. Wtedy będę miał funkcję, która oblicza wartość klucza, który obecnie nie jest buforowany.Pamięć podręczna oparta na mapach z wartościami wygaśnięcia i miękkości

MapMaker().softValues 
      .expireAfterWrite(10, TimeUnit.MINUTES) 
      .makeComputingMap(Function(...)); 

Jaki jest najlepszy sposób na zrobienie tego w Scali?

+0

Jeśli to działa dobrze dla ciebie w języku Java, dlaczego robi to inaczej w Scali? Nie jestem świadomy żadnych specyficznych dla scala bibliotek. –

+4

Cóż, miałem nadzieję na bardziej idiotyczną odpowiedź. Podczas gdy Google Guava jest znakomity, raczej nie będę musiał uwzględniać zależności, gdy biblioteki kolekcji Scali są tak dobrze napisane, jak są. –

+0

I tylko FYI 'MapMaker(). SoftValues' jest teraz [przestarzałe] (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/MapMaker.html#softValues ​​()), zamiast tego użyj 'CacheBuilder.softValues ​​()'. – sbeliakov

Odpowiedz

6

Jak powiedziała Kim, dlaczego jest inaczej, jeśli MapMaker działa dobrze?

import collection.JavaConverters._ 
val cache = /* your MapMaker code creating a Java map */.asScala 

Teraz można uzyskać dostęp do podstawowej mapy Java za pomocą metod z mapy Scala.

+1

To prawda, ale jak powiedziałem do Kima, musi być coś więcej w stylu Scala? –

+0

@Ben, nie z pudełka, które znam. –

1

Stworzyłem funkcjonalną, przezroczystą mapę expiracji w Scali. Dodawanie i usuwanie elementów daje nową mapę, która usuwa również wszelkie wygasłe wartości.

Expiration Map

0

jestem nadal używać rozwiązanie cache Guava w Scala jak dobrze :)

Przede wszystkim, jak wspomniano w jednym z komentarzy, w nowszych wersjach Guava Cache, MapMaker() jest teraz przestarzała i zamiast tego powinieneś użyć CacheBuilder.

Więc teraz, w Scala to będzie wyglądać następująco:

lazy val cachedData = CacheBuilder.newBuilder() 
    .expireAfterWrite(60, TimeUnit.MINUTES) 
    .maximumSize(10) 
    .build(
     new CacheLoader[Key, Data] { 
     def load(key: Key): Data = { 
      veryExpansiveDataCreation(key) 
     } 
     } 
    ) 

Aby dowiedzieć się od niego, można użyć coś takiego:

def cachedData(ketToData: Key): Data = { 
    try { 
     return cachedData.get(ketToData) 
    } catch { 
     case ee: Exception => throw new YourSpecialException(ee.getMessage); 
    } 
    }