Closed GoogleCodeExporter closed 9 years ago
That is a danger in using a simple hash code algorithm. The List class in Java
exhibits the same behavior:
groovy:000> l1 = new LinkedList();
===> []
groovy:000> l1.add(429l);
===> true
groovy:000> l1.add("57");
===> true
groovy:000> l1.hashCode();
===> 15958
groovy:000> l2 = new LinkedList();
===> []
groovy:000> l2.add(430l);
===> true
groovy:000> l2.add("47");
===> true
groovy:000> l2.hashCode();
===> 15958
If collisions like this are possible in your code please change to one of the
other key generation classes. If you still want to use hashes for keys the
MessageDigestCacheKeyGenerator will not be susceptible to this problem.
We're also considering changing the default key generator to the
StringCacheKeyGenerator for the 1.2 release.
Original comment by eric.dalquist
on 14 Dec 2010 at 2:25
[deleted comment]
[deleted comment]
This is very very dangerous. Plz change the implementation to
/**
* @author Eric Dalquist
* @version $Revision: 454 $
*/
public class HashCodeCacheKeyGenerator extends
AbstractHashingCacheKeyGenerator<HashCodeCacheKeyGenerator.LongGenerator, Long>
{
/**
* Little utility class to fake a mutable long
*/
public static class LongGenerator {
protected static final long [] MULTIPLIERS = {31, 37, 41, 43, 47, 53, 59, 61, 67, 71};
private long hash = 1;
private int index = 0;
private LongGenerator() {
}
public void append(long hash) {
this.hash = MULTIPLIERS[index++ % MULTIPLIERS.length] * this.hash + hash;
}
}
/**
* @see com.googlecode.ehcache.annotations.key.AbstractCacheKeyGenerator#AbstractCacheKeyGenerator()
*/
public HashCodeCacheKeyGenerator() {
}
/**
* @see com.googlecode.ehcache.annotations.key.AbstractCacheKeyGenerator#AbstractCacheKeyGenerator(boolean, boolean)
*/
public HashCodeCacheKeyGenerator(boolean includeMethod, boolean includeParameterTypes) {
super(includeMethod, includeParameterTypes);
}
@Override
public LongGenerator getGenerator(Object... data) {
return new LongGenerator();
}
@Override
public Long generateKey(LongGenerator generator) {
return generator.hash;
}
@Override
protected void append(LongGenerator generator, boolean[] a) {
for (final boolean element : a) {
generator.append(element ? 1231 : 1237);
}
}
@Override
protected void append(LongGenerator generator, byte[] a) {
for (final byte element : a) {
generator.append(element);
}
}
@Override
protected void append(LongGenerator generator, char[] a) {
for (final char element : a) {
generator.append(element);
}
}
@Override
protected void append(LongGenerator generator, double[] a) {
for (final double element : a) {
generator.append(Double.doubleToLongBits(element));
}
}
@Override
protected void append(LongGenerator generator, float[] a) {
for (final float element : a) {
generator.append(Float.floatToIntBits(element));
}
}
@Override
protected void append(LongGenerator generator, int[] a) {
for (final int element : a) {
generator.append(element);
}
}
@Override
protected void append(LongGenerator generator, long[] a) {
for (final long element : a) {
generator.append(element);
}
}
@Override
protected void append(LongGenerator generator, short[] a) {
for (final short element : a) {
generator.append(element);
}
}
@Override
protected void appendGraphCycle(LongGenerator generator, Object o) {
generator.append(0);
}
@Override
protected void appendNull(LongGenerator generator) {
generator.append(0);
}
@Override
protected void appendHash(LongGenerator generator, Object e) {
if (e instanceof Double) {
generator.append(Double.doubleToLongBits(((Double)e).doubleValue()));
}
else if (e instanceof Long) {
generator.append(((Long)e).longValue());
}
else {
generator.append(e.hashCode());
}
}
}
Original comment by bernd.zu...@gmail.com
on 17 Apr 2012 at 1:03
Original issue reported on code.google.com by
gray.b...@gmail.com
on 14 Dec 2010 at 10:11