根据时间戳条件删除 Caffeine 条目
Delete Caffeine entries based on a timestamp condition
有没有办法根据时间戳条件删除咖啡因条目?例如。,
在 T1
我有以下条目
K1 -> V1
K2 -> V2
K3 -> V3
时间 T2
我只更新 K2
和 K3
。 (我不知道这两个条目是否会有 exact 时间戳。K2
可能有 T2
但 K3
可能是 T2 + some nanos
。但是为了这个问题让我们假设他们这样做)
现在我希望咖啡因使条目 K1 -> V1
无效,因为 T1 < T2
.
执行此操作的一种方法是遍历条目并检查它们的写入时间戳是否 < T2
。收集这些密钥,最后调用 invalidateKeys(keys)
.
也许有一种非迭代的方式?
如果您使用的是expireAfterWrite
,那么您可以获得按时间戳顺序排列的条目快照。由于此调用需要获得逐出锁,因此它提供了一个不可变的快照而不是迭代器。那很乱,例如您必须提供一个可能不正确的限制,它取决于到期时间。
Duration maxAge = Duration.ofMinutes(1);
cache.policy().expireAfterWrite().ifPresent(policy -> {
Map<K, V> oldest = policy.oldest(1_000);
for (K key : oldest.keySet()) {
// Remove everything written more than 1 minute ago
policy.ageOf(key)
.filter(duration -> duration.compareTo(maxAge) > 0)
.ifPresent(duration -> cache.invalidate(key));
}
});
如果您自己维护时间戳,则可以使用 cache.asMap()
视图进行无序迭代。这可能是最简单和快速的。
long cutoff = ...
var keys = cache.asMap().entrySet().stream()
.filter(entry -> entry.getValue().timestamp() < cutoff)
.collect(toList());
cache.invalidateAll(keys);
一种行不通但值得一提的方法是变量过期,expireAfter(expiry)
。您可以根据先前的设置为每次阅读设置新的持续时间。这在条目返回给调用者后生效,因此虽然您可以立即过期,但它将服务 K1
(至少)一次。
否则,您可以在缓存外的检索时间进行验证并依赖于大小逐出。这种方法的缺陷是它确实会污染缓存中的死条目。
V value = cache.get(key);
if (value.timestamp() < cutoff) {
cache.asMap().remove(key, value);
return cache.get(key); // load a new value
}
return value;
或者您可以维护自己的写入顺序队列等。所有这些都会随着您的喜好而变得混乱。对于您的情况,完整迭代可能是最简单且最不容易出错的方法。
有没有办法根据时间戳条件删除咖啡因条目?例如。,
在 T1
我有以下条目
K1 -> V1
K2 -> V2
K3 -> V3
时间 T2
我只更新 K2
和 K3
。 (我不知道这两个条目是否会有 exact 时间戳。K2
可能有 T2
但 K3
可能是 T2 + some nanos
。但是为了这个问题让我们假设他们这样做)
现在我希望咖啡因使条目 K1 -> V1
无效,因为 T1 < T2
.
执行此操作的一种方法是遍历条目并检查它们的写入时间戳是否 < T2
。收集这些密钥,最后调用 invalidateKeys(keys)
.
也许有一种非迭代的方式?
如果您使用的是expireAfterWrite
,那么您可以获得按时间戳顺序排列的条目快照。由于此调用需要获得逐出锁,因此它提供了一个不可变的快照而不是迭代器。那很乱,例如您必须提供一个可能不正确的限制,它取决于到期时间。
Duration maxAge = Duration.ofMinutes(1);
cache.policy().expireAfterWrite().ifPresent(policy -> {
Map<K, V> oldest = policy.oldest(1_000);
for (K key : oldest.keySet()) {
// Remove everything written more than 1 minute ago
policy.ageOf(key)
.filter(duration -> duration.compareTo(maxAge) > 0)
.ifPresent(duration -> cache.invalidate(key));
}
});
如果您自己维护时间戳,则可以使用 cache.asMap()
视图进行无序迭代。这可能是最简单和快速的。
long cutoff = ...
var keys = cache.asMap().entrySet().stream()
.filter(entry -> entry.getValue().timestamp() < cutoff)
.collect(toList());
cache.invalidateAll(keys);
一种行不通但值得一提的方法是变量过期,expireAfter(expiry)
。您可以根据先前的设置为每次阅读设置新的持续时间。这在条目返回给调用者后生效,因此虽然您可以立即过期,但它将服务 K1
(至少)一次。
否则,您可以在缓存外的检索时间进行验证并依赖于大小逐出。这种方法的缺陷是它确实会污染缓存中的死条目。
V value = cache.get(key);
if (value.timestamp() < cutoff) {
cache.asMap().remove(key, value);
return cache.get(key); // load a new value
}
return value;
或者您可以维护自己的写入顺序队列等。所有这些都会随着您的喜好而变得混乱。对于您的情况,完整迭代可能是最简单且最不容易出错的方法。