Concurrent cache
A similar class to the LockingLazyVar class is the Cache class. An instance of this class declares a concurrent cache of values that you can look up quickly and in a thread-safe way. The cache is similar to a Least Recently Used (LRU) cache. Because the Cache class uses the Java concurrency libraries, access to the cache is thread-safe. Each entry in the cache is defined by a key, which is also called an input value. A block uses the value of the key to calculate the value of the cache entry.
The constructor for a cache requires:
- A name as a
String. The implementation uses this name to generate logging for cache misses. - The size, as a number of slots.
- A block that defines a function to calculate a value from a key. Typically, this calculation is resource-intensive.
Use the key and value types to parameterize the Cache type using Gosu generics
syntax. For example, if you need to pass a String to the cache and get an
Integer back, create a
new Cache<String, Integer>.
To use the cache, call the get method and pass an input value,
which is the key. If the value for the key is in the cache, get returns that value. If the
value is not cached, Gosu calls the block to calculate the value from
the key and then caches the result. On any subsequent call of the get method, the value is the same
but Gosu uses the cached value, if it is still in the cache. If too many
items were added to the cache and the required item is unavailable, Gosu
reruns the block to regenerate the value. Gosu then caches the result
again.
To use a cache within another class, you can define a static instance of the cache. The static variable definition defines your block. Because the Cache class uses the Java concurrency libraries, this static implementation is thread-safe. For example, in your class definition, define a static variable like this:
static var _myCache = new Cache<String, Integer>( "StrToInt", 1000, \ str -> getMyInt( str ) )To use your cache, get a value
from the cache using code like the following. In this example, inputString is a String variable that may or may
not contain a String that
you used before with this cache:
var fastValue = _myCache.get( inputString )The first time you call the
get method, Gosu calls
the block to generate the Integer
value.
On any subsequent call of the get method, the value is the same but Gosu uses the cached value, if it is still in the cache. If too many items were added to the cache and the required item is unavailable, Gosu reruns the block to regenerate the value. Gosu then caches the result again in the concurrent cache object.
An even better way to use the cache is to abstract the cache implementation into a property accessor function. A private static object Cache object, as shown in the previous example, can handle the actual cache. For example, define a property accessor function such as:
static property get function MyInt( str : String ) {
return _myCache.get( str )
}
These code examples are demonstrations that have a simple operation in the block. Typically, the overhead of maintaining the cache is appropriate if your calculation is resource-intensive and you expect repeated access with the same input values.
