1 /* 2 * Created: Apr 15, 2013 3 */ 4 package org.xerial.snappy; 5 6 import java.util.Random; 7 8 /** 9 * Generates random data with specific expected snappy performance characteristics. 10 * <p/> 11 * <p> 12 * This has been copied from <a href="https://github.com/dain/snappy"> dain's snappy</a> implementation.. 13 * </p> 14 */ 15 public class RandomGenerator 16 { 17 18 public final byte[] data; 19 public int position; 20 RandomGenerator(double compressionRatio)21 public RandomGenerator(double compressionRatio) 22 { 23 // We use a limited amount of data over and over again and ensure 24 // that it is larger than the compression window (32KB), and also 25 // large enough to serve all typical value sizes we want to write. 26 Random rnd = new Random(301); 27 data = new byte[1048576 + 100]; 28 for (int i = 0; i < 1048576; i += 100) { 29 // Add a short fragment that is as compressible as specified ratio 30 System.arraycopy(compressibleData(rnd, compressionRatio, 100), 0, 31 data, i, 100); 32 } 33 } 34 getNextPosition(int length)35 public int getNextPosition(int length) 36 { 37 if (position + length > data.length) { 38 position = 0; 39 assert (length < data.length); 40 } 41 int result = position; 42 position += length; 43 return result; 44 } 45 46 private static byte[] compressibleData(Random random, 47 double compressionRatio, int length) 48 { 49 int raw = (int) (length * compressionRatio); 50 if (raw < 1) { 51 raw = 1; 52 } 53 byte[] rawData = generateRandomData(random, raw); 54 55 // Duplicate the random data until we have filled "length" bytes 56 byte[] dest = new byte[length]; 57 for (int i = 0; i < length; ) { 58 int chunkLength = Math.min(rawData.length, length - i); 59 System.arraycopy(rawData, 0, dest, i, chunkLength); 60 i += chunkLength; 61 } 62 return dest; 63 } 64 65 private static byte[] generateRandomData(Random random, int length) 66 { 67 byte[] rawData = new byte[length]; 68 for (int i = 0; i < rawData.length; i++) { 69 rawData[i] = (byte) random.nextInt(256); 70 } 71 return rawData; 72 } 73 }