CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-github-ben-manes-caffeine--jcache

JSR-107 JCache compatibility adapter for Caffeine caching library

Pending
Overview
Eval results
Files

cache-operations.mddocs/

Cache Operations

The Cache Operations system provides the complete JSR-107 Cache interface implementation with both synchronous and asynchronous operations. The CacheProxy and LoadingCacheProxy classes implement all standard caching operations backed by Caffeine's high-performance cache engine.

Capabilities

Basic Cache Operations

Core caching functionality for storing, retrieving, and checking cache entries.

/**
 * Get value by key, returns null if not present
 * @param key the key to look up
 * @return the associated value or null
 */
public @Nullable V get(K key);

/**
 * Get multiple values by keys
 * @param keys the set of keys to look up
 * @return map of found key-value pairs
 */
public Map<K, V> getAll(Set<? extends K> keys);

/**
 * Check if a key exists in the cache
 * @param key the key to check
 * @return true if key exists and hasn't expired
 */
public boolean containsKey(K key);

/**
 * Store a key-value pair in the cache
 * @param key the key to store
 * @param value the value to associate with the key
 */
public void put(K key, V value);

/**
 * Store multiple key-value pairs in the cache
 * @param map the map of key-value pairs to store
 */
public void putAll(Map<? extends K, ? extends V> map);

/**
 * Store key-value pair only if key is not already present
 * @param key the key to store
 * @param value the value to associate with the key
 * @return true if the key was absent and value was stored
 */
public boolean putIfAbsent(K key, V value);

Usage Examples:

Cache<String, Integer> cache = cacheManager.getCache("numbers", String.class, Integer.class);

// Basic operations
cache.put("one", 1);
cache.put("two", 2);

Integer value = cache.get("one"); // Returns 1
boolean exists = cache.containsKey("two"); // Returns true

// Bulk operations
Map<String, Integer> batch = Map.of(
    "three", 3,
    "four", 4,
    "five", 5
);
cache.putAll(batch);

Set<String> keys = Set.of("one", "three", "five");
Map<String, Integer> results = cache.getAll(keys);

// Conditional put
boolean added = cache.putIfAbsent("six", 6); // Returns true
boolean notAdded = cache.putIfAbsent("six", 60); // Returns false, value unchanged

Atomic Operations

Thread-safe atomic operations that combine read and write operations.

/**
 * Atomically get current value and store new value
 * @param key the key to update
 * @param value the new value to store
 * @return the previous value or null if key was absent
 */
public @Nullable V getAndPut(K key, V value);

/**
 * Atomically get current value and remove the entry
 * @param key the key to remove
 * @return the previous value or null if key was absent
 */
public V getAndRemove(K key);

/**
 * Atomically get current value and replace with new value
 * @param key the key to replace
 * @param value the new value to store
 * @return the previous value or null if key was absent
 */
public V getAndReplace(K key, V value);

/**
 * Replace value only if current value equals expected value
 * @param key the key to replace
 * @param oldValue the expected current value
 * @param newValue the new value to store
 * @return true if replacement occurred
 */
public boolean replace(K key, V oldValue, V newValue);

/**
 * Replace value only if key is currently mapped to some value
 * @param key the key to replace
 * @param value the new value to store
 * @return true if replacement occurred
 */
public boolean replace(K key, V value);

Usage Examples:

Cache<String, AtomicInteger> counters = cacheManager.getCache("counters", String.class, AtomicInteger.class);

// Initialize counter
counters.put("requests", new AtomicInteger(0));

// Atomic get-and-update operations
AtomicInteger oldCounter = counters.getAndPut("requests", new AtomicInteger(1));
AtomicInteger removedCounter = counters.getAndRemove("requests");

// Conditional replacement
counters.put("status", new AtomicInteger(0));
boolean replaced = counters.replace("status", new AtomicInteger(0), new AtomicInteger(1));

// Simple replacement
boolean updated = counters.replace("status", new AtomicInteger(2));

Removal Operations

Various methods for removing entries from the cache.

/**
 * Remove entry by key
 * @param key the key to remove
 * @return true if key was present and removed
 */
public boolean remove(K key);

/**
 * Remove entry only if current value equals expected value
 * @param key the key to remove
 * @param oldValue the expected current value
 * @return true if removal occurred
 */
public boolean remove(K key, V oldValue);

/**
 * Remove multiple entries by keys
 * @param keys the set of keys to remove
 */
public void removeAll(Set<? extends K> keys);

/**
 * Remove all entries from the cache
 */
public void removeAll();

/**
 * Clear all entries from the cache without triggering listeners
 */
public void clear();

Usage Examples:

Cache<String, String> cache = cacheManager.getCache("data", String.class, String.class);

// Populate cache
cache.putAll(Map.of("key1", "value1", "key2", "value2", "key3", "value3"));

// Remove single entry
boolean removed = cache.remove("key1"); // Returns true

// Conditional removal
boolean conditionalRemove = cache.remove("key2", "value2"); // Returns true
boolean failedRemove = cache.remove("key3", "wrongValue"); // Returns false

// Bulk removal
cache.removeAll(Set.of("key2", "key3"));

// Remove all entries
cache.removeAll(); // Triggers entry removed events

// Clear cache (no events)
cache.clear();

Asynchronous Loading

Support for asynchronous cache loading with completion callbacks.

/**
 * Asynchronously load multiple entries, optionally replacing existing values
 * @param keys the set of keys to load
 * @param replaceExistingValues whether to replace existing cached values
 * @param completionListener callback for completion or failure notification
 */
public void loadAll(Set<? extends K> keys, 
                   boolean replaceExistingValues, 
                   CompletionListener completionListener);

Usage Examples:

Cache<String, User> userCache = cacheManager.getCache("users", String.class, User.class);

// Asynchronous loading with completion listener
Set<String> userIds = Set.of("user1", "user2", "user3");

userCache.loadAll(userIds, false, new CompletionListener() {
    @Override
    public void onCompletion() {
        System.out.println("Loading completed successfully");
    }
    
    @Override
    public void onException(Exception e) {
        System.err.println("Loading failed: " + e.getMessage());
    }
});

// Loading with replacement
userCache.loadAll(userIds, true, null); // No completion listener

Entry Processing

Atomic entry processing operations for complex cache manipulations.

/**
 * Atomically process a single cache entry
 * @param key the key to process
 * @param entryProcessor the processor to apply
 * @param arguments additional arguments for the processor
 * @return result from the entry processor
 */
public <T> @Nullable T invoke(K key, EntryProcessor<K, V, T> entryProcessor, Object... arguments);

/**
 * Atomically process multiple cache entries
 * @param keys the set of keys to process
 * @param entryProcessor the processor to apply
 * @param arguments additional arguments for the processor
 * @return map of processing results
 */
public <T> Map<K, EntryProcessorResult<T>> invokeAll(Set<? extends K> keys, 
                                                    EntryProcessor<K, V, T> entryProcessor, 
                                                    Object... arguments);

Usage Examples:

Cache<String, Integer> cache = cacheManager.getCache("counters", String.class, Integer.class);

// Entry processor to increment counter
EntryProcessor<String, Integer, Integer> incrementProcessor = 
    (entry, arguments) -> {
        Integer current = entry.getValue();
        if (current == null) {
            current = 0;
        }
        Integer newValue = current + 1;
        entry.setValue(newValue);
        return newValue;
    };

// Process single entry
Integer result = cache.invoke("counter1", incrementProcessor);

// Process multiple entries
Set<String> keys = Set.of("counter1", "counter2", "counter3");
Map<String, EntryProcessorResult<Integer>> results = 
    cache.invokeAll(keys, incrementProcessor);

// Handle results
for (Map.Entry<String, EntryProcessorResult<Integer>> entry : results.entrySet()) {
    try {
        Integer value = entry.getValue().get();
        System.out.println(entry.getKey() + " = " + value);
    } catch (EntryProcessorException e) {
        System.err.println("Processing failed for " + entry.getKey() + ": " + e.getMessage());
    }
}

LoadingCacheProxy

Extended cache implementation with automatic loading capabilities.

/**
 * Extended cache that automatically loads missing entries using configured CacheLoader
 */
public final class LoadingCacheProxy<K, V> extends CacheProxy<K, V> {
    /**
     * Get value by key, loading if necessary using the configured CacheLoader
     * @param key the key to look up
     * @return the associated value (loaded if not present)
     * @throws CacheException if loading fails
     */
    @Override
    public @Nullable V get(K key);
    
    /**
     * Get multiple values by keys, loading missing entries as needed
     * @param keys the set of keys to look up
     * @return map of key-value pairs (missing entries are loaded)
     * @throws CacheException if loading fails
     */
    @Override
    public Map<K, V> getAll(Set<? extends K> keys);
}

Usage Examples:

// Configure cache with loader
CaffeineConfiguration<String, User> config = new CaffeineConfiguration<String, User>()
    .setTypes(String.class, User.class)
    .setCacheLoaderFactory(() -> new DatabaseUserLoader())
    .setReadThrough(true);

Cache<String, User> userCache = cacheManager.createCache("users", config);

// Automatic loading on cache miss
User user = userCache.get("user123"); // Loads from database if not cached

// Bulk loading
Set<String> userIds = Set.of("user1", "user2", "user3");
Map<String, User> users = userCache.getAll(userIds); // Loads missing users

Cache Metadata

Access to cache metadata and administrative operations.

/**
 * Get the cache name
 * @return the name of this cache
 */
public String getName();

/**
 * Get the associated cache manager
 * @return the CacheManager that created this cache
 */
public CacheManager getCacheManager();

/**
 * Check if the cache is closed
 * @return true if the cache has been closed
 */
public boolean isClosed();

/**
 * Close the cache and release resources
 */
public void close();

/**
 * Get cache configuration
 * @param clazz the configuration class to retrieve
 * @return immutable copy of the configuration
 */
public <C extends Configuration<K, V>> C getConfiguration(Class<C> clazz);

/**
 * Unwrap cache to specific implementation type
 * @param clazz the class to unwrap to
 * @return unwrapped instance
 */
public <T> T unwrap(Class<T> clazz);

/**
 * Get iterator over cache entries
 * @return iterator for cache entries
 */
public Iterator<Cache.Entry<K, V>> iterator();

Install with Tessl CLI

npx tessl i tessl/maven-com-github-ben-manes-caffeine--jcache

docs

cache-management.md

cache-operations.md

configuration.md

events.md

index.md

integration.md

management.md

spi.md

tile.json