0

I would like to cache the following data entity map object for each userId.

/**
 * Example data object
 */
data class Data(
  val id: Int,
  val name: String,
  val age: Int
)

As one of the ideas, I considered the following cache in Caffeine.

/**
 * Ex.1 cache
 * userId to (dataId to Data)
 */
val userDataCache = Caffeine.newBuilder()
  .build<Int, ConcurrentHashMap<Int, Data>>()

/**
 * invalidate by userId
 */
fun invalidate(userId: Int) {
  userDataCache.invalidate(userId)
}

However, the userDataCache in the above example is not thread-safe because it is defined as a nested hashmap.

I've prepared another idea to make it thread-safe.

/**
 * Ex.2 cache
 * Pair(userId, dataId) to Data
 */
val userDataCache = Caffeine.newBuilder()
  .build<Pair<Int, Int>, Data>()

/**
 * invalidate by userId
 */
fun invalidate(userId: Int) {
  TODO("No idea !!!")
}

This method is thread-safe because it does not use a nested hashmap.

However, this method does not allow us to define an invalidate method to invalidate the cache for each userId.

How can I use Caffeine Cache or ConcurrentHashMap in a way that satisfies the following requirements?

  • Cache the data map per userId
  • Invalidate the data map per userId
  • Make it thread-safe
  • Welcome to StackOverflow! The answer to your question might depend on what your cache is for. How many times do you expect to be inserting into, reading, and invalidating the cache, and from how many different threads? – Sam Jul 23 '21 at 20:34
  • Thanks for the answer! We assume that reading, inserting, updating, and invalidating the cache will be done in about 2 or 3 threads per userId at most. – y-hashida Jul 26 '21 at 15:51
  • You could use a `Map.compute` method for exclusive write access, e.g. to update the mappings. (It is unclear what you mean by the nested map not being thread safe) – Ben Manes Jul 26 '21 at 19:08

0 Answers0