package org.apache.cassandra.stress.generatedata; import java.nio.ByteBuffer; import java.security.MessageDigest; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import org.apache.cassandra.utils.FBUtilities; import static com.google.common.base.Charsets.UTF_8; public class DataGenStringRepeats extends DataGen { private static final ConcurrentHashMap<Integer, ConcurrentHashMap<Long, byte[]>> CACHE_LOOKUP = new ConcurrentHashMap<>(); private final ConcurrentHashMap<Long, byte[]> cache; private final int repeatFrequency; public DataGenStringRepeats(int repeatFrequency) { if (!CACHE_LOOKUP.containsKey(repeatFrequency)) CACHE_LOOKUP.putIfAbsent(repeatFrequency, new ConcurrentHashMap<Long, byte[]>()); cache = CACHE_LOOKUP.get(repeatFrequency); this.repeatFrequency = repeatFrequency; } @Override public void generate(ByteBuffer fill, long index) { fill(fill, index, 0); } @Override public void generate(List<ByteBuffer> fills, long index) { for (int i = 0 ; i < fills.size() ; i++) { fill(fills.get(i), index, i); } } private void fill(ByteBuffer fill, long index, int column) { fill.clear(); byte[] trg = fill.array(); byte[] src = getData(index, column); for (int j = 0 ; j < trg.length ; j += src.length) System.arraycopy(src, 0, trg, j, Math.min(src.length, trg.length - j)); } private byte[] getData(long index, int column) { final long key = (column * repeatFrequency) + (index % repeatFrequency); byte[] r = cache.get(key); if (r != null) return r; MessageDigest md = FBUtilities.threadLocalMD5Digest(); r = md.digest(Long.toString(key).getBytes(UTF_8)); cache.putIfAbsent(key, r); return r; } @Override public boolean isDeterministic() { return true; } }