package edu.brown.benchmark.wikipedia.util;
import java.util.Arrays;
import java.util.Random;
/**
* Fast Random Text Generator
* @author pavlo
*/
public abstract class TextGenerator {
private static final int CHAR_START = 32; // [space]
private static final int CHAR_STOP = 126; // [~]
private static final char[] CHAR_SYMBOLS = new char[1 + CHAR_STOP - CHAR_START];
static {
for (int i = 0; i < CHAR_SYMBOLS.length; i++) {
CHAR_SYMBOLS[i] = (char)(CHAR_START + i);
} // FOR
} // STATIC
/**
* Generate a random block of text as a char array
* @param rng
* @param strLen
* @return
*/
public static char[] randomChars(Random rng, int strLen) {
char chars[] = new char[strLen];
for (int i = 0; i < chars.length; i++) {
chars[i] = (char)CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)];
} // FOR
return (chars);
}
public static char[] randomChars(Random rng, char chars[], int start, int stop) {
for (int i = start; i < stop; i++) {
chars[i] = (char)CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)];
} // FOR
return (chars);
}
/**
* Returns a new string filled with random text
* @param rng
* @param strLen
* @return
*/
public static String randomStr(Random rng, int strLen) {
return new String(randomChars(rng, strLen));
}
/**
* Returns a new string filled with random text. The first characters
* of the string will be filled with the prefix
* @param rng
* @param strLen
* @param prefix
* @return
*/
public static String randomStr(Random rng, int strLen, String prefix) {
// Generate the random chars and then add in our prefix
char chars[] = randomChars(rng, strLen);
prefix.getChars(0, Math.min(prefix.length(), strLen), chars, 0);
return new String(chars);
}
/**
* Resize the given block of text by the delta and add random characters
* to the new space in the array. Returns a new character array
* @param rng
* @param orig
* @param delta
* @return
*/
public static char[] resizeText(Random rng, char orig[], int delta) {
assert(orig.length + delta > 0) :
String.format("Invalid resize (orig:%d, delta:%d)", orig.length, delta);
char chars[] = Arrays.copyOf(orig, orig.length + delta);
for (int i = orig.length; i < chars.length; i++) {
chars[i] = (char)CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)];
} // FOR
return (chars);
}
/**
* Permute a random portion of the origin text
* Returns the same character array that was given as input
* @param rng
* @param chars
* @return
*/
public static char[] permuteText(Random rng, char chars[]) {
// We will try to be fast about this and permute the text by blocks
int idx = 0;
int blockSize = chars.length / 32;
// We'll generate one random number and check whether its bit is set to zero
// Hopefully this is faster than having to generate a bunch of random
// integers
int rand = rng.nextInt();
// If the number is zero, then flip one bit so that we make sure that
// we change at least one block
if (rand == 0) rand = 1;
for (int bit = 0; bit < 32; bit++) {
if ((rand>>bit & 1) == 1) {
for (int i = 0; i < blockSize; i++) {
chars[idx + i] = (char)CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)];
} // FOR
}
idx += blockSize;
if (idx >= chars.length) break;
} // FOR
return (chars);
}
}