2016-09-28 45 views
0

我目前正在一些运行在关系数据库(PostgreSQL)和图形一(Neo4j)上的算法运行比较实验。 我实现了我的算法,作为Neo4j的用户定义过程,但它看起来不像它开箱即用执行任何缓存。 有没有办法在Neo4j中为用户定义的过程配置缓存?为Neo4j用户定义的过程缓存

感谢

回答

0

你必须自己实现缓存,如果是相关的使用情况和你有什么要缓存:可能是一些不相关的交易,所以没有节点或关系; 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和实现)。 适用于可缓存值的限制也适用于密钥。

这是一个永恒的,无界的缓存。如果您需要更多功能(过期,最大大小),我建议您使用真实缓存实施,如GuavaCache(或LoadingCache)或Ben Manes的Caffeine

+0

谢谢,我希望有一些开箱即用的东西,所以我可以比较缓存实现,但会尝试一个你建议的库而不是我自己创建的转储库。 –