package com.yahoo.dtf.range; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Random; import com.yahoo.dtf.range.Range; import com.yahoo.dtf.range.RangeFactory; import com.yahoo.dtf.exception.DTFException; import com.yahoo.dtf.exception.RangeException; public class RandomListRange extends Range { public final static int MAXSIZE = 10*1024; private String[] elements = null; private long generated = 0; private Random _rand = null; public RandomListRange() { } public static boolean matches(String expression) { return expression.startsWith("random(") && expression.endsWith(")"); } public RandomListRange(String expression) throws RangeException { _rand = new Random(System.nanoTime()); String arguments = expression.substring("random(".length(), expression.length()-1); String subrange = arguments; try { Range range = RangeFactory.getRange(subrange); if (range.size() < MAXSIZE) { elements = new String[range.size()]; int i = 0; while(range.hasMoreElements()) { String element = range.nextElement(); elements[i++] = element; } } else throw new RangeException("Random ranges cannot exceed " + MAXSIZE + " elements."); } catch (DTFException e) { throw new RangeException("Error parsing range.",e); } } public boolean hasMoreElements() { return (generated < elements.length); } public String nextElement() { int rand = _rand.nextInt(); synchronized(this) { generated++; return elements[Math.abs(rand % elements.length)]; } } public void reset() { generated = 0; } public int size() { return elements.length; } @Override public void restoreState(DataInputStream dis) throws RangeException { _rand = new Random(System.currentTimeMillis()); try { generated = dis.readLong(); int size = dis.readInt(); elements = new String[size]; for (int i = 0; i < elements.length; i++) elements[i] = dis.readUTF(); } catch (IOException e) { throw new RangeException("Unable to restore range.",e); } } @Override public void suspendState(DataOutputStream dos) throws RangeException { try { dos.writeLong(generated); dos.writeInt(elements.length); for (int i = 0; i < elements.length; i++) dos.writeUTF(elements[i]); } catch (IOException e) { throw new RangeException("Unable to suspend range.",e); } } }