самый короткий toString как ключ ehcache - PullRequest
0 голосов
/ 29 июня 2011

Я использовал ehcache с аннотациями ehcache-spring-annotations. В первый раз мы выбираем HashCodeCacheKeyGenerator. Это было довольно хорошо. но 1 месяц назад мы нашли «дублирование ключа». Поэтому мы заменили HashCodeCacheKeyGenerator на StringCacheKeyGenerator. проблема с «дублированием ключа» исчезла, но огромный ключ toString (с использованием apache ToStringBuilder) выделил кучу памяти (около 200 МБ) Потому что параметр объекта (объекта значения) имеет огромное поле.

Я сделал очень очень простую строку, как показано ниже

VerySimpleToStringStyle$Ta,,,,,1|2|3,1|2|3,a|b|c,true|false,64|65|66,1.0|2.0|3.0,1.0|2.0|3.0,,,,,,,1|2|3,[a, b, c],{b=2, c=3, a=1},a|1|false|{b=2, c=3, a=1}|[a, b, c],A,[b, c, a],,,

Как видите, нет имени поля и значения, если значение равно нулю. Я надеюсь использовать SHA256, MD5 хэширование по поводу оригинальной toString, но мы с коллегами беспокоимся о «дублировании ключа».

Есть ли у идеи самый короткий метод toString объекта с большим значением в качестве ключа ehcache?

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public class VerySimpleToStringStyle extends ToStringStyle {
private static final long serialVersionUID = -8388711512639784062L;

public VerySimpleToStringStyle() {
     super();
     this.setUseClassName(true);
     this.setUseIdentityHashCode(false);
     this.setUseFieldNames(false);
     this.setContentStart("");
     this.setContentEnd("");
     this.setNullText("");

     this.setFieldSeparatorAtStart(false);
     this.setFieldSeparator(",");
     this.setFieldSeparatorAtEnd(false);

     this.setArrayStart("");
     this.setArraySeparator("|");
     this.setArrayEnd("");

}

private static class T {
    private String a = "a";
    private String a1 = null;
    private String cc1;
    private String cc2;
    private String cc3;
    private int[] i = new int[] {1, 2, 3};
    private long[] l = new long[] {1, 2, 3};
    private char[] c = new char[] {'a', 'b', 'c'};
    private boolean[] bl = new boolean[] {true, false};
    private byte[] b = new byte[] {64, 65, 66};
    private float[] f = new float[] {1, 2, 3};
    private double[] d = new double[] {1, 2, 3};
    private String bb1;
    private String bb2;
    private String bb3;
    private String bb4;
    private String bb5;
    private String bb6;
    private short[] s = new short[] {1, 2, 3};
    private List<String> list = new ArrayList<String>();
    private Map<String, String> m = new HashMap<String, String>();
    private Object[] o = new Object[] {"a", 1, false, m, list};
    private enum E {A, B, C};
    private E e = E.A;
    private static String x = "x";
    private transient String y = "y";
    private Set<String> set = new HashSet<String>();
    private String aa1;
    private String aa2;
    private String aa3;

    public T() {
        this.list.add("a");
        this.list.add("b");
        this.list.add("c");

        this.m.put("a", "1");
        this.m.put("b", "2");
        this.m.put("c", "3");

        this.set.add("a");
        this.set.add("b");
        this.set.add("c");
    }
}

public static void main(String[] args) {
    System.out.println(ToStringBuilder.reflectionToString(new T(), new VerySimpleToStringStyle()));
}
}

Ответы [ 2 ]

0 голосов
/ 11 июля 2011

Как и в первом ответе, ответ заключается в использовании реальной функции хеширования.Генератор ключей по умолчанию просто использует метод Java hashCode.

Попробуйте MessageDigestCacheKeyGenerator: http://code.google.com/p/ehcache-spring-annotations/wiki/MessageDigestCacheKeyGenerator

. Он может использовать любой алгоритм хеширования, поддерживаемый API Java MessageDigest, при конфигурации по умолчанию генерируется SHA-1 хеш ключевых данных.

0 голосов
/ 29 июня 2011

Хеш-функции, такие как sha256 и MD5, в основном будут в порядке.Проблема с дублированным ключом обычно называется конфликтом ключей.Нет АБСОЛЮТНО никакого способа гарантировать, что столкновение не произойдет, потому что есть конечные возможности, которые генерирует хеш-функция.Качество хеш-функции сделает коллизию менее вероятной, но не невозможной.

Чтобы коллизия никогда не происходила, но при этом уменьшите размер сгенерированного ключа, то вы можете максимизировать энтропию в ключе, созданном с использованием значений.Проще говоря, используйте функцию сжатия, чтобы быть ключом.Тем не менее, в вашем случае сборщик toString, похоже, взял всю информацию об объекте для создания ключа, что лишает цель иметь кеш, поскольку ключ уже содержит всю необходимую вам информацию.Вместо этого ключ должен быть своего рода уникальным идентификатором объекта, который вы пытаетесь кэшировать.

Итак, во-первых, определите, что можно использовать в качестве уникального идентификатора, так как ключ важнее, чем то, как его сгенерировать.

И найти способ справиться со столкновением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...