I just wonder if there is any caching solution available in Scala. I'm looking for something like it is provided by Guava in Java.
Should I use Guava too in Scala? Is there a wrapper / pimp in Scalaz or something similar? Any alternative more appropriate for Scala devs?
What Guava provides:
LoadingCache<Key, Graph> CACHE= CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.removalListener(MY_LISTENER)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});
Supplier<Animal> singleAnimalCache = Suppliers.memoizeWithExpiration(animalFromDbSupplier(), 365, TimeUnit.DAYS);
I need some basic cache management like in Guava.
We had the same requirements and ended up building wrappers around Guava. We recently open-sourced parts of the library called Mango. If you don’t mind the extra dependency you can use it like
import org.feijoas.mango.common.cache._
import org.feijoas.mango.common.base.Suppliers._
val MY_LISTENER = (remNot: RemovalNotification[Key, Graph]) => ()
// > MY_LISTENER : RemovalNotification[Key,Graph] => Unit = <function1>
val CACHE = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.removalListener(MY_LISTENER)
.build { (key: Key) => new Graph() }
// > CACHE : LoadingCache[Key,Graph] = <function1>
val animalFromDbSupplier = () => {
// load from db
new Animal()
}
// > animalFromDbSupplier : () => Animal = <function0>
val singleAnimalCache = memoizeWithExpiration(animalFromDbSupplier, 365, TimeUnit.DAYS)
// > singleAnimalCache : () => Animal = Suppliers.memoizeWithExpiration(<function0>, 365, DAYS)
Just adding an answer to plug my own project, but I recommend ScalaCache.
https://github.com/cb372/scalacache
Is there a wrapper / pimp in Scalaz or something similar?
In Scalaz 7 there's Memo
, which I covered a bit in learning Scalaz day 16.
It's the first thing Adam Rosien covered in scalaz "For the Rest of Us" talk, so check that out too. He's using Scalaz 6.
Using guava caching is straightforward in Scala.
import com.google.common.base._
import com.google.common.cache._
object Simple_Guava_Caches_in_Scala {
def main(args: Array[String]): Unit = {
// Simple scala guava cache
val simpleCache1 =
CacheBuilder
.newBuilder()
.build(new CacheLoader[String, String] {
def load(key: String): String = {
println(s"Simple scala guava cache, heavy work calculating $key")
s"It's me $key"
}
})
println(simpleCache1.get("1"))
println(simpleCache1.get("1"))
println(simpleCache1.get("2"))
println(simpleCache1.get("2"))
println(simpleCache1.get("2"))
// Simple scala guava supplier cache / factory
println()
val supplier_cache: Supplier[String] = Suppliers.memoize(
() => {
println("Simple scala guava supplier cache / factory, heavy work creating singleton:")
"It's me"
}
)
println(supplier_cache.get)
println(supplier_cache.get)
println(supplier_cache.get)
}
}
This is producing
Simple scala guava cache, heavy work calculating 1
It's me 1
It's me 1
Simple scala guava cache, heavy work calculating 2
It's me 2
It's me 2
It's me 2
Simple scala guava supplier cache / factory, heavy work creating singleton:
It's me
It's me
It's me
I've added this to build.sbt
:
libraryDependencies += "com.github.cb372" %% "scalacache-guava" % "0.26.0"
Would be interesting to transform the coding above to cb372's scalacache-guava. Could be even simpler/more standardized.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With