Cache¶
Configure Memory Cache with System Eviction Policy¶
class Employee {
String id;
String name;
Employee(String id, String name) {
this.id = id;
this.name = name;
}
}
Employee value = null;
int maxSize = 5;//Max number of entries
MemoryCache<String, Employee> cache = new MemoryCache<>(context, maxSize);
cache.clearOnMemoryError().build();
cache.put("001", new Employee("001", "Peggy Smith"));
cache.put("002", new Employee("002", "James Cole"));
cache.put("003", new Employee("003", "John King"));
cache.put("004", new Employee("004", "Jim Kelly"));
cache.put("005", new Employee("005", "Mary Sheep"));
// Cache full at this point since max entries limit reached
value = cache.get("005");//updates entry use time, LRU policy
assertNotNull(value);
value = cache.get("001");//updates entry use time, LRU policy
assertNotNull(value);
// Adding this entry should result in eviction of one LRU item
cache.put("006", new Employee("006", "Mona Lew"));
value = cache.get("006");
assertNotNull(value);
// Now "002" should have been evicted but not "001" since it was used once
value = cache.get("002");
assertNull(value);
internal inner class Employee(var id: String, var name: String)
var value: Employee? = null
val maxSize = 5//Max number of entries
val cache = MemoryCache<String, Employee>(context, maxSize)
cache.clearOnMemoryError().build()
cache.put("001", Employee("001", "Peggy Smith"))
cache.put("002", Employee("002", "James Cole"))
cache.put("003", Employee("003", "John King"))
cache.put("004", Employee("004", "Jim Kelly"))
cache.put("005", Employee("005", "Mary Sheep"))
// Cache full at this point since max entries limit reached
value = cache.get("005")//updates entry use time, LRU policy
assertNotNull(value)
value = cache.get("001")//updates entry use time, LRU policy
assertNotNull(value)
// Adding this entry should result in eviction of one LRU item
cache.put("006", Employee("006", "Mona Lew"))
value = cache.get("006")
assertNotNull(value)
// Now "002" should have been evicted but not "001" since it was used once
value = cache.get("002")
assertNull(value)
Configure Memory Cache with Cost Factor Based Eviction Policy¶
class Employee {
String id;
String name;
Employee(String id, String name) {
this.id = id;
this.name = name;
}
}
int maxSize = 5;//total cache capacity by size is 5
MemoryCache<String, Employee> cache = new MemoryCache<>(context, maxSize);
cache.maxCost(35d);//total cache capacity by cost of entries
cache.clearOnMemoryError().addCostFactor(new CacheCostFactor<String>() {
public List<String> onExceedMaxCost(List<String> existingKeys) {
ArrayList<String> removeList = new ArrayList<>();
int size = existingKeys.size();
// existingKeys entries are sorted by cost in an ascending order so
// costliest entry is at the end
int i = 1;
while (i <= 3) { //remove at most 3 entries
if ((size -i) >= 0) {
removeList.add(existingKeys.get(size - i));
}
i++;
}
return removeList;
}}).build();
cache.put("001", new Employee("001", "James Kelly"), 7d);
cache.put("002", new Employee("002", "Jimmy Buffet"), 10d);
cache.put("003", new Employee("003", "Nat Cole"), 5d);
cache.put("004", new Employee("004", "Tom Petty"), 9d);
// Total cost of entries up to this point is 31d
Employee value = cache.get("004");
assertNotNull(value);
value = cache.get("001");
assertNotNull(value);
// Adding an entry will trigger cache clean up though number of entries is less than max size
// and clean up will remove the 3 most costly items per cost factor function
cache.put("005", new Employee("005", "Etta James"), 7d);
// Note: Above put could fail when the cost of the new entry cost is high enough but
// the memory freed is not enough. Another attempt to insert would succeed if sufficient
// entries are cleaned-up by previous put().
// These entries should have been cleaned-up
value = cache.get("001");
assertNull(value);
value = cache.get("002");
assertNull(value);
value = cache.get("004");
assertNull(value);
// This entry should still be there
value = cache.get("003");
assertNotNull(value);
value = cache.get("005");
assertNotNull(value);
//Another out, should not clean-up any other entry
cache.put("006", new Employee("006", "Justin Who"), 7d);
value = cache.get("006");
assertNotNull(value);
value = cache.get("005");
assertNotNull(value);
value = cache.get("003");
assertNotNull(value);
internal inner class Employee(var id: String, var name: String)
val maxSize = 5//total cache capacity by size is 5
val cache = MemoryCache<String, Employee>(context, maxSize)
cache.maxCost(35.0)//total cache capacity by cost of entries
cache.clearOnMemoryError().addCostFactor(CacheCostFactor<String> { existingKeys ->
val removeList = ArrayList<String>()
val size = existingKeys.size
// existingKeys entries are sorted by cost in an ascending order so
// costliest entry is at the end
var i = 1
while (i <= 3) { //remove at most 3 entries
if (size - i >= 0) {
removeList.add(existingKeys[size - i])
}
i++
}
removeList
}).build()
cache.put("001", Employee("001", "James Kelly"), 7.0)
cache.put("002", Employee("002", "Jimmy Buffet"), 10.0)
cache.put("003", Employee("003", "Nat Cole"), 5.0)
cache.put("004", Employee("004", "Tom Petty"), 9.0)
// Total cost of entries up to this point is 31d
var value = cache.get("004")
assertNotNull(value)
value = cache.get("001")
assertNotNull(value)
// Adding an entry will trigger cache clean up though number of entries is less than max size
// and clean up will remove the 3 most costly items per cost factor function
cache.put("005", Employee("005", "Etta James"), 7.0)
// Note: Above put could fail when the cost of the new entry cost is high enough but
// the memory freed is not enough. Another attempt to insert would succeed if sufficient
// entries are cleaned-up by previous put().
// These entries should have been cleaned-up
value = cache.get("001")
assertNull(value)
value = cache.get("002")
assertNull(value)
value = cache.get("004")
assertNull(value)
// This entry should still be there
value = cache.get("003")
assertNotNull(value)
value = cache.get("005")
assertNotNull(value)
//Another out, should not clean-up any other entry
cache.put("006", Employee("006", "Justin Who"), 7.0)
value = cache.get("006")
assertNotNull(value)
value = cache.get("005")
assertNotNull(value)
value = cache.get("003")
assertNotNull(value)
Set Up Persistent Cache Using Secure Store¶
class Employee implements Serializable{
String id;
String name;
}
SecureStoreCache<Employee> cache = new SecureStoreCache<>(context, 100, "mySecureCache");
try {
cache.open(null);//Uses internally generated encryption key
} catch (OpenFailureException ex) {
logger.error("Failed to open secure store cache", ex);
}
// Use cache
// ...
// Close when done
cache.close();
internal inner class Employee(var id: String, var name: String) : Serializable
val cache = SecureStoreCache<Employee>(context!!, 100, "mySecureCache")
try {
cache.open(null)//Uses internally generated encryption key
} catch (ex: OpenFailureException) {
logger.error("Failed to open secure store cache", ex)
}
// Use cache
// ...
// Close when done
cache.close()
Set Up Composite Cache (Multi-Layer Cache)¶
class Employee implements Serializable{
String id;
String name;
}
MemoryCache<String, Employee> cache1 = new MemoryCache<>(context, 16);
SecureStoreCache<Employee> cache2 = new SecureStoreCache<>(context, 100, "oneSecureCache");
try {
cache2.open(null); //Uses built-in mechanism to generate an encryption key
} catch (OpenFailureException ex) {
logger.error("Failed to open secure store cache", ex);
}
// cache2 is a persistent cache that implements the Cache interface.
CompositeCache<String, Employee> compositeCache = new CompositeCache<String,
Employee>(context)
.add(cache1) // The first level cache-- MemoryCache.
.add(cache2) // The second level cache-- a backing store.
.build();
// When done, make sure to close the persistent cache
cache2.close();
internal inner class Employee(var id: String, var name: String) : Serializable
val cache1 = MemoryCache<String, Employee>(context, 16)
val cache2 = SecureStoreCache<Employee>(context!!, 100, "oneSecureCache")
try {
cache2.open(null) //Uses built-in mechanism to generate an encryption key
} catch (ex: OpenFailureException) {
logger.error("Failed to open secure store cache", ex)
}
// cache2 is a persistent cache that implements the Cache interface.
val compositeCache = CompositeCache<String, Employee>(context)
.add(cache1) // The first level cache-- MemoryCache.
.add(cache2) // The second level cache-- a backing store.
.build()
// When done, make sure to close the persistent cache
cache2.close()
Last update: June 23, 2023