Pergunta

I am new to Guava cache and looking for some advice.

I would like to cache "functions" - classes responsible for some calculation. Each class has 3 double attributes: start, max, increment

What is the best way to create a key for storing in cache? How about complex object?

I was thinking about using Hasher but for complex objects same hash does not mean same object. So the key-> value will not be unique.

Also, how does Cache look up for key? I noticed that if I use 2 objects for key which pass equals, Cache considers it to be unique keys. Does it work based on 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();
            }
        }
    }
}

Output is:

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

Removing weakKeys() solves the problem. Is this expected?

Foi útil?

Solução

Read the docs for weakKeys:

Warning: when this method is used, the resulting cache will use identity (==) comparison to determine equality of keys.

So yes, you should stop using weakKeys, and you're also probably better off having a proper value object instead of concatenating things together into a String.

Outras dicas

If the arguments are String, concatenate all of the arguments to your function with a delimiter. This will uniquely define the result. If the arguments are numeric or a combination of both you can encode them into a ByteBuffer and use it's hashCode as the key to save memory. If the argument data is large (perhaps +32 bytes) you can encode the key using a digest algorithm such as MD5 and use the result as a key. In this case, you would need to weigh the processing cost of generating a digest as opposed to computing your cached result.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top