- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我完全重写了这个问题,因为原来的问题无法解决。为了简单起见,我使用斐波那契数列作为玩具示例。
trivial recursive cached computation正如预期的那样,以非常长的堆栈跟踪结束。这就是为什么我想要一个像 IterativeLoadingCache 这样的抽象类,我可以扩展为 here通过类似的东西
@Override
protected Integer computeNonRecursivelly(Integer key) {
final Integer x1 = getOrEnqueue(key-1);
final Integer x2 = getOrEnqueue(key-2);
if (x1==null) return null;
if (x2==null) return null;
return x1+x2;
}
它会在不使用递归的情况下处理所有缓存和计算。
我真的不是在寻找斐波那契数列的有效计算。我需要一些允许将缓存与递归函数一起使用的东西,递归深度可以达到任意高。
我已经找到了一种解决方案,但是它效率很低而且非常丑陋,所以我希望得到一些好的建议。我也很好奇是否有人需要它或者是否已经实现了它。
最佳答案
由于您重写了问题,这里有一个新答案。
首先,在我看来,您对 computeNonRecursivelly
的实现仍然是递归的,因为 getOrEnqueue
调用了它。
我不认为你可以直接使用 Cache
,因为你需要在计算中有 2 个步骤:一个声明所需值的依赖关系,一个计算一次满足依赖关系。不过,它只有在您永远没有循环依赖项的情况下才有效(这与递归中的要求相同)。
那样的话,您可以将尚未在缓存中的依赖项(及其依赖项等)排队,然后以正确的顺序计算它们。类似的东西:
public abstract class TwoStepCacheLoader<K, V> extends CacheLoader<K, V> {
public abstract Set<K> getDependencies(K key);
}
public class TwoStepCache<K, V> extends ForwardingLoadingCache<K, V> {
private final TwoStepCacheLoader<K, V> loader;
private LoadingCache<K, V> cache;
public TwoStepCache(TwoStepCacheLoader<K, V> loader) {
this.loader = loader;
cache = CacheBuilder.newBuilder().build(loader);
}
@Override
public V get(K key)
throws ExecutionException {
V value = cache.getIfPresent(key);
if (value != null) {
return value;
}
Deque<K> toCompute = getDependenciesToCompute(key);
return computeDependencies(toCompute);
}
private Deque<K> getDependenciesToCompute(K key) {
Set<K> seen = Sets.newHashSet(key);
Deque<K> dependencies = new ArrayDeque<K>(seen), toCompute = new ArrayDeque<K>(seen);
do {
for (K dependency : loader.getDependencies(dependencies.remove())) {
if (seen.add(dependency) && // Deduplication in the dependencies
cache.getIfPresent(dependency) == null) {
// We need to compute it.
toCompute.push(dependency);
// We also need its dependencies.
dependencies.add(dependency);
}
}
} while (!dependencies.isEmpty());
return toCompute;
}
private V computeDependencies(Deque<K> toCompute)
throws ExecutionException {
V value;
do {
value = cache.get(toCompute.pop());
} while (!toCompute.isEmpty());
// The last computed value is for our key.
return value;
}
@Override
public V getUnchecked(K key) {
try {
return get(key);
} catch (ExecutionException e) {
throw new UncheckedExecutionException(e.getCause());
}
}
@Override
protected LoadingCache<K, V> delegate() {
return cache;
}
}
现在您可以实现一个安全调用缓存的 TwoStepCacheLoader
:
public class Fibonacci {
private LoadingCache<Integer, Integer> cache = new TwoStepCache<Integer, Integer>(new FibonacciCacheLoader());
public int fibonacci(int n) {
return cache.getUnchecked(n);
}
private class FibonacciCacheLoader extends TwoStepCacheLoader<Integer, Integer> {
@Override
public Set<Integer> getDependencies(Integer key) {
if (key <= 1) {
return ImmutableSet.of();
}
return ImmutableSet.of(key - 2, key - 1);
}
@Override
public Integer load(Integer key)
throws Exception {
if (key <= 1) {
return 1;
}
return cache.get(key - 2) + cache.get(key - 1);
}
}
}
我已经对其进行了单元测试,它似乎运行正常。
关于java - 如何使用 LoadingCache 将递归转换为迭代?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11153173/
Google 提供了“loading cache ”,其描述如下: A semi-persistent mapping from keys to values. Values are automati
在guava中,使用LoadingCache时会同步调用CacheLoader。但是,我的 load() 操作可能需要太长时间(~1 秒),我想采取默认操作以防它花费太长时间(>200 毫秒)并异步加
我使用 Map 容器作为 LoadingCache 中的值: @Service public class SlideCacheSpace { @Value("${value}") pr
我有一个数据结构,其中有对象,并且它们有目标。并且它们之间是多对多的关系。例如:object1 具有目标:t1、t2、t3 和object2 有目标:t2、t3。 我想编写一个 Guava Loadi
我有一个像这样的loadingcache类: LoadingCache> parents 其中 Parent 是一个具有 id、description、home 和 nickname asMap();
我完全重写了这个问题,因为原来的问题无法解决。为了简单起见,我使用斐波那契数列作为玩具示例。 trivial recursive cached computation正如预期的那样,以非常长的堆栈跟踪
我正在使用 CacheBuilder和 LoadingCache实现数据库数据的内存缓存。 假设客户端在缓存中查询后备存储中不存在的项目。我想让客户端知道没有找到指定键的数据。处理此问题的最佳方法是什
我需要在每天的特定时间刷新我的缓存,在我的例子中,是在午夜。我有办法用 Guava LoadingCache 做到这一点吗?到目前为止,我只在一天后使用下一个代码更新了缓存: private fina
我有一个像这样的加载缓存: MyCacheLoader loader=new MyCacheLoader(); MyRemovalListener listener=new MyRemovalList
我正在使用 Guava LoadingCache 来存储数据库查询的结果。但是,尽管没有设置逐出策略,但通过 getFromCache() 获取缓存会导致每次都命中 CacheLoader load(
我在我的项目中使用 Guava 的 LoadingCache 来处理线程{安全、友好}的缓存加载,它工作得非常好。但是,有一个限制。 当前定义缓存的代码如下所示: cache = CacheBuild
当我单独运行它们时,我为 Caffeine CacheLoader 实现编写的单元测试(JUnit、Mockito)全部成功,但当我一起运行它们时,其中一个测试失败了。我相信我在所有测试对象设置中都遵
我正在使用 Guava LoadingCache 向其中填充一些数据,并且我想每 1 分钟从该 LoadingCache 中删除所有条目。 public class MetricHolder {
我正在使用 Guava LoadingCache 将所有元素一次批量加载到我的急切缓存中。但是执行loadAll我提供的方法实际上并不需要 Iterable keys 参数,因为我的 DAO 也不排除
我希望添加几个不同的 LoadingCache到 Spring CacheManager ,但是我不明白如何使用 CaffeineCacheManager 实现这一点。看来只有一个加载器可以刷新内容,
我正在使用一个允许用户更改其显示名称的帐户系统。为了实现这一点,每个用户都有一个 UUID 。在我的程序中的各个点,我可能有一个 UUID 并想要其当前的显示名称,或者我可能有一个当前的显示名称并且我
我正在使用 Guava 的 Loading Cache缓存 HTTP 请求的结果。 Kotlin/KTOR 提供了一个 HTTP Client Library基于协程(即非阻塞 HTTP 请求)。 我
要在 spring boot 应用程序中本地缓存一些数据,哪种技术在读/写操作方面会更好?HashMap vs ConcurrentHashMap vs LoadingCache( Guava 库)我
我正在使用 Java7,并且正在配置 Apache Ignite(版本 2.7.5),其中服务器/客户端已启动并运行。但是,客户端无法从对象中检索 Guavas LoadingCache 变量(但是检
我正在尝试利用 Guava 库中的 LoadingCache 来缓存 LinkedList。 LoadingCache> cache; 我已经设置了一个 CacheLoader 来处理未命中,它工作正
我是一名优秀的程序员,十分优秀!