2014-03-12 217 views
0

我是新来的Guava缓存并寻求一些建议。选择Guava Cache的密钥

我想缓存“函数” - 类负责一些计算。每个类有3个双重属性:开始,最大,增量

创建密钥以存储在缓存中的最佳方式是什么?复杂的对象怎么样?

我正在考虑使用哈希,但对于复杂的对象相同的哈希并不意味着同一个对象。所以key->值不会是唯一的。

另外,Cache如何查找密钥? 我注意到,如果我使用2个对象传递等于的密钥,Cache认为它是唯一密钥。它是基于key1 == key2工作的吗?

public static void testGuavaCache() { 
    Cache<Object, String> CACHE = CacheBuilder.newBuilder().weakKeys().weakValues().build(); 

    for (int i = 0; i < 2; i++) { 
     Joiner joiner = Joiner.on('|'); 
     String key1 = joiner.join(i, i, i, i, i, i, i); 

     for (int j = 0; j < 2; j++) { 
      String key = joiner.join(i, i, i, i, i, i, i); 
      System.out.println(key1.equals(key)); 
      System.out.println(key1 == key); 
      try { 
       String m = CACHE.get(key, new Callable<String>() { 
        @Override 
        public String call() throws Exception { 
         return "test"; 
        } 
       }); 

       System.out.println("Size = " + CACHE.size()); 

      } catch (ExecutionException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

输出是:

true 
false 
Size = 1 
true 
false 
Size = 2 
true 
false 
Size = 3 
true 
false 
Size = 4 

卸下weakKeys()解决了这个问题。这是预期的吗?

+0

你的对象创建真的很贵吗?如果不是,则根据需要忘记任何缓存并重新创建。 – maaartinus

回答

2

阅读docs为weakKeys

警告:当使用这种方法,所得到的高速缓存将使用标识(==)比较以确定密钥的平等。

所以,是的,你应该停止使用weakKeys,而你也可能会更好过有一个适当的值对象,而不是一起串联东西放进String

+0

谢谢。答案是RTFM :) – YaRiK

-1

如果参数是String,则用分隔符将所有参数连接到函数。这将唯一地定义结果。如果参数是数字或两者的组合,则可以将它们编码为ByteBuffer并将其hashCode用作保存内存的关键字。如果参数数据很大(可能是+32字节),则可以使用摘要算法(如MD5)对密钥进行编码,并将结果用作关键字。在这种情况下,您需要权衡生成摘要的处理成本,而不是计算缓存结果。