我目前正在一些运行在关系数据库(PostgreSQL)和图形一(Neo4j)上的算法运行比较实验。 我实现了我的算法,作为Neo4j的用户定义过程,但它看起来不像它开箱即用执行任何缓存。 有没有办法在Neo4j中为用户定义的过程配置缓存?为Neo4j用户定义的过程缓存
感谢
我目前正在一些运行在关系数据库(PostgreSQL)和图形一(Neo4j)上的算法运行比较实验。 我实现了我的算法,作为Neo4j的用户定义过程,但它看起来不像它开箱即用执行任何缓存。 有没有办法在Neo4j中为用户定义的过程配置缓存?为Neo4j用户定义的过程缓存
感谢
你必须自己实现缓存,如果是相关的使用情况和你有什么要缓存:可能是一些不相关的交易,所以没有节点或关系; Neo4j的ID很棘手,因为它们可以被重用,所以最好只缓存它们,或者根本不缓存它们。应用程序级别的ID将会很好,就像由字符串或标量类型组成的bean一样。
假设你有定义了这个过程:
public class MyProcedure {
@Context
public GraphDatabaseService db;
@Procedure
public Stream<MyBean> doSomething(@Name("uuid") String uuid) {
int count = 0;
// ...
return Stream.of(new MyBean(count));
}
public static class MyBean {
public int count;
public MyBean(int count) {
this.count = count;
}
}
}
您可以使用ConcurrentMap
添加一些简单的缓存:
public class MyProcedure {
private static final ConcurrentMap<String, Collection<MyBean>> CACHE =
new ConcurrentHashMap<>();
@Context
public GraphDatabaseService db;
@Procedure
public Stream<MyBean> doSomething(@Name("uuid") String uuid) {
Collection<MyBean> result = CACHE.computeIfAbsent(uuid,
k -> doSomethingCacheable(k).collect(Collectors.toList()));
return result.stream();
}
private Stream<MyBean> doSomethingCacheable(String uuid) {
int count = 0;
// ...
return Stream.of(new MyBean(count));
}
public static class MyBean {
// ...
}
}
请注意,您不能缓存Stream
因为它只能被消耗一次,所以你必须通过收集到一个ArrayList
(你也可以在该方法内移动collect
,将返回类型改为Collection<MyBean>
并使用方法引用)来自己使用它。如果该过程需要多个参数,则需要为组合键创建合适的类(如果可能,请使用不变的正确的equals
和实现)。 适用于可缓存值的限制也适用于密钥。
这是一个永恒的,无界的缓存。如果您需要更多功能(过期,最大大小),我建议您使用真实缓存实施,如Guava的Cache
(或LoadingCache
)或Ben Manes的Caffeine。
谢谢,我希望有一些开箱即用的东西,所以我可以比较缓存实现,但会尝试一个你建议的库而不是我自己创建的转储库。 –