Skip to content

Commit

Permalink
feat(cache) per object ttl for cache items. This adds TTL capibilites…
Browse files Browse the repository at this point in the history
… to our CaffineCache and really deprecates the timed cache provider.

ref:#30670
  • Loading branch information
wezell committed Nov 15, 2024
1 parent 4c5d2c5 commit e6e83e2
Show file tree
Hide file tree
Showing 5 changed files with 306 additions and 180 deletions.
19 changes: 19 additions & 0 deletions dotCMS/src/main/java/com/dotcms/cache/CacheValue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.dotcms.cache;

import java.io.Serializable;

public class CacheValue implements Serializable {

public final Object value;
public final long ttlInMillis;

public CacheValue(Object value, long ttlInMillis) {
this.value = value;
this.ttlInMillis = ttlInMillis <= 0 ? Long.MAX_VALUE : ttlInMillis;
}

public CacheValue(Object value) {
this.value = value;
this.ttlInMillis = Long.MAX_VALUE;
}
}
88 changes: 88 additions & 0 deletions dotCMS/src/main/java/com/dotcms/cache/DynamicTTLCache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.dotcms.cache;


import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.Expiry;
import com.github.benmanes.caffeine.cache.stats.CacheStats;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.validation.constraints.NotNull;

public class DynamicTTLCache<K, V> {

public final long defaultTTLInMillis;
private final Cache<K, CacheValue> cache;

public DynamicTTLCache(long maxCapacity) {
this(maxCapacity, Long.MAX_VALUE);
}


public DynamicTTLCache(long maxCapacity, long defaultTTLInMillis) {
this.defaultTTLInMillis = defaultTTLInMillis;
this.cache = Caffeine.newBuilder()
.initialCapacity((int) maxCapacity)
.expireAfter(new Expiry<K, CacheValue>() {
@Override
public long expireAfterCreate(@NotNull K key, @NotNull CacheValue value, long currentTime) {
return value != null ? TimeUnit.MILLISECONDS.toNanos(value.ttlInMillis)
: TimeUnit.MILLISECONDS.toNanos(defaultTTLInMillis);
}

@Override
public long expireAfterUpdate(K key, CacheValue value, long currentTime,
long currentDuration) {
return currentDuration;
}

@Override
public long expireAfterRead(K key, CacheValue value, long currentTime, long currentDuration) {
return currentDuration;
}
})
.maximumSize(maxCapacity)
.build();
}

public void put(K key, Object value, long ttlInMillis) {

if(value instanceof CacheValue) {
cache.put(key, (CacheValue) value);
}else{
cache.put(key, new CacheValue(value, ttlInMillis ));
}

}

public void put(K key, Object value) {
this.put(key, value, defaultTTLInMillis);
}

public Object getIfPresent(K key) {
CacheValue cacheValue = cache.getIfPresent(key);

return cacheValue != null ? cacheValue.value : null;
}

public void invalidate(K key) {
cache.invalidate(key);
}

public void invalidateAll() {

cache.invalidateAll();
}

public CacheStats stats() {
return cache.stats();
}

public long estimatedSize() {
return cache.estimatedSize();
}

public Map<K, CacheValue> asMap() {
return cache.asMap();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.dotmarketing.business.cache.provider;

import com.dotmarketing.util.Logger;
import java.io.Serializable;
import java.util.Set;

Expand Down Expand Up @@ -67,6 +68,11 @@ public abstract class CacheProvider implements Serializable {
*/
public abstract boolean isInitialized () throws Exception;

public void put(String group, String key, Object content, long ttlMillis){
Logger.warn(this.getClass(), "This cache implementation does not support per object TTL, ignoring it.");
put(group, key, content);
}

/**
* Adds the given content to the given region and for the given key
*
Expand Down Expand Up @@ -132,4 +138,4 @@ public abstract class CacheProvider implements Serializable {
*/
public abstract void shutdown ();

}
}
Loading

0 comments on commit e6e83e2

Please sign in to comment.