Categories
Programming

Using guava cache with scala

Guava cache provides a whole lot of features when it comes to caching in memory, lets see how we can make use of it in scala.

Getting the dependencies

if you are using SBT, add the following dependency (of course, get the latest version)

"com.google.guava" % "guava" % "28.1-jre"

Building the cache

Now lets build a cache, for this example, I’ll build a generic cache with a size constraint as well as a ttl for the values.

class GCache[K, V](size: Int, ttl_minutes: Int) {

  private val cache = CacheBuilder.newBuilder()
    .recordStats()
    .maximumSize(size)
    .expireAfterAccess(ttl_minutes.toLong, TimeUnit.MINUTES)
    .asInstanceOf[CacheBuilder[K, V]]
    .build[K, V]

  def get(key: K, loader: Callable[V]) = cache.get(key, loader)

}

Accessing the cache

Usually one want to cache the things that takes time to compute, if you notice, you could see the second argument to the get method is a loader – which basically is our expensive operation, we’ll be caching the value of this operation. So next time if we call the get with the same key, the value will already be present in the cache and hence we avoid the expensive operation.

//Instantiate the cache
val cache = new GCache[String, String](10000, 10)

//Create a loader
case class GCacheLoader(key: String) extends Callable[String] {
  override def call(): String = {
    println("Some expensive operation here")
    s"$key-${UUID.randomUUID().toString}"
  }
}

//Usage
assert(cache.get("one", GCacheLoader("one")).startsWith("one"))
assert(cache.get("one", GCacheLoader("one")).startsWith("one"))
assert(cache.get("two", GCacheLoader("two")).startsWith("two"))
You can see the println is being called twice (one for ‘one’ and another for ‘two’)

Example code base is available here.

Leave a Reply

Your email address will not be published. Required fields are marked *