FVT és a FIFO cache Scala felesleges függőségek, programozó jegyzetek

Ritkán súlyos alkalmazása ma nem Gyorsítótár nélkül semmit. Néhány FVT gyorsítótárat elemi valósul meg, például a hash táblák és kettős kapcsolt listák. De nem az a tény, hogy a megoldás különbözik különösen hatékony, így a legjobb, hogy kihasználják a kész végrehajtását. Gyakran a megvalósítás javasoljuk Guava vagy LruMap a twitter-util. De ezek a megoldások az a hátrányuk, különösen a stack-en hagyományosan kötődik, hogy a Scala 2.10, és a guava csak szörnyű.

Szerencsére Scala könnyen, hogy egy egyszerű Kheshig nem húzza szükségtelen függőségek projektben. A Java világ, széles körben ismert vétel overaydom eljárás removeEldestEntry osztály LinkedHashMap kinyerését teszi lehetővé FVT cache. Fogadása ez nem túl elegáns, de még mindig nem olyan rossz, mint Guava. Lefordítva Scala ez így néz ki:

import java. util. # 123; Térkép, LinkedHashMap # 125;

def makeCache # 91; K, V # 93; # 40; kapacitását. Int # 41;. térkép # 91; K, V # 93; = # 123;
új LinkedHashMap # 91; K, V # 93; # 40; kapacitás, 0.7F, igaz # 41; # 123;
privát val cacheCapacity = kapacitás

felülírhatja def removeEldestEntry # 40; bejegyzést. Térkép. belépés # 91; K, V # 93; # 41;. boolean = # 123;
ezt. méret # 40; # 41;> ez. cacheCapacity
# 125;
# 125;
# 125;

scala> case osztály Dog (név: String)
definiált osztály Dog

scala> Val cache = makeCache [String, Dog] (3)
cache: java.util.Map [String, Dog] = <>

scala> Option (cache.get ( "8"))
res2: Opció [Kutya] = Némely (kutya (8))

scala> Option (cache.get ( "ololo"))
res4: Opció [Kutya] = Nincs

Megjegyezzük, hogy cache.get csomagolva opció, mivel ez dzhavny LinkedHashMap és kap a módszer return null. De primitív típusok (int, és hasonlók), visszatér az alapértelmezett érték:

scala> Val cache = makeCache [String, Int] (3)
cache: java.util.Map [String, int] = <>

scala> cache.get ( "teszt")
res5: Int = 0

scala> Val cache = makeCache [karakterlánc, logikai érték] (3)
cache: java.util.Map [karakterlánc, logikai érték] = <>

scala> cache.get ( "teszt")
res6: Boolean = false

Ezért előfordulhat, hogy a használni kívánt módszer containsKey:

scala> cache.containsKey ( "teszt")
res7: Boolean = false

Azt is figyelembe kell venni, hogy ha a keshom futhat több áramot egy időben, megy, hogy csomagolja be synchonized:

scala> cache.synchronized
res8: Boolean = false

Most tekintsük a második módszer.

A Scala is LinkedHashMap, de nincs érv accessOrder, a dzhavnom LinkedHashMap, azzal az eredménnyel, hogy lehet beszerezni csak FIFO cache:

import scala. gyűjtemény. _

Val cacheCapacity = 10000
val cacheMutex = new Object # 40; # 41;
var cache = változékony. LinkedHashMap # 91; String, Long # 93; # 40; # 41;

// írási gyorsítótár
cacheMutex. szinkronizált # 123;
cache. tesz # 40; „Kulcs”. 100500 # 41;
cache = gyorsítótár. csepp # 40; cache. méret - cacheCapacity # 41;
# 125;

// olvasható a cache
cacheMutex. szinkronizált # 123; cache. kap # 40; „Kulcs” # 41; # 125;

Itt a get metódus visszaadja egy lehetőséget. Tisztítja a cache „kézzel” módszerrel csepp. Sőt, ez a módszer visszatér egy új LinkedHashMap, így szinkronizálja a cache hozzáférést igényel egy külön objektum cacheMutex. Azt is figyelembe kell venni, hogy a hatékonysági szempontok miatt érdemes nem dobja minden bejegyzés a cache:

// írási gyorsítótár
cacheMutex. szinkronizált # 123;
cache. tesz # 40; „Kulcs”. 100500 # 41;
ha # 40; cache. méret> cacheCapacity # 41; # 123;
cache = gyorsítótár. csepp # 40; cache. mérete - # 40; cacheCapacity. toDouble * 0,75 # 41;. toInt # 41;
# 125;
# 125;

És általában, lehetőség van erre egy külön téma.

Mondanom sem kell, sok más módon lehet létrehozni egy gyorsítótárat Scala, de a két tűnik számomra a legegyszerűbb. Természetesen a valós alkalmazások sokkal érdekesebb, mert a cache nem kell válnia a valós adatok vagy cache más nodah cache szükség lehet osztani több, így nem lesz a szűk keresztmetszet, és így tovább.

És hogyan csinálod cache?