Reputation: 4605
I have a flat file which consists of a list of device identifiers. When my Java/tomcat based application receives a request from a particular device, it decides the business logic based on presence of the device identifier in the file (The device identifier MAY or MAY NOT be there in the file even though the device exists). Also, there are use cases when
To make the (multi-threaded) application faster, instead of directly accessing the file for every read/write operation, I need to store the content in-memory.
Here are the requirements (summary) :
Read the content of the file in memory (cache) during the application start up.
Read the content from the cache in a multi-threaded manner. If the content is not there in the cache it should not be there in the file and vice versa (Single point of truth).
When there is a new device identity, the cache as well as file needs to updated.
When there is a need to delete a device identity, the cache as well as file needs to updated.
The application runs in Java.
What are the options available? I initially thought of using gauva cache. But, I am not sure if it supports writing it's content back to the source file or not. Even a simple properties file (java.util.properties) should also do. But, not sure if that will be suitable in a highly multi-threaded environment.
Appreciate your suggestions.
Upvotes: 0
Views: 1535
Reputation: 9591
Like most caches, Guava's is designed to be used primarily in a read-through manner. The intent is that the authoritative data source is updated and the cache is then invalidated. The cache does not support write-through or write-behind, and adding those capabilities on top may lead to subtle race conditions.
The Java 8 rewrite, Caffeine, supports adding that functionality through ConcurrentHashMap's atomic compute methods. A write-through uses a compute
that updates the data source and, if successful, stores the value in the cache. A write-behind uses a compute
method that asynchronously updates the data source and optimistically stores the value in the cache. In both cases, if the entry exists during a compute then the read is non-blocking and receives the old value until the update completes.
Neither write-through nor write-behind are good approaches for common usages of an in-memory caches. When appropriate they require more thoughtful care and customization, so supplying generic support was thought to lead developers astray and provide little benefit. The rewrite provided the opportunity to make the functionality possible, without promoting it directly.
Upvotes: 4
Reputation: 3576
As a starting point using the HashSet as an extension point.
class DeviceCache extends HashSet<Device> {
boolean add(Device d) {
boolean rv = super.add(d);
if (!rv) {
... Add the device to the file.
}
return rv;
}
remove(Device d) {
boolean rv = super.remove(d);
if (rv) {
... Remove the device from the file
}
return fv;
}
}
It is far from complete. Any thoughts?
Upvotes: 1