/** * */ package com.github.lpezet.antiope.samples.yahoo; import java.lang.reflect.Array; import java.util.Iterator; import java.util.Random; /** * @author luc * */ public class Distribution<T> { private static class CircularIterator<T> implements Iterator<T> { private Object mLock = new Object(); private Distribution<T> mDist; private int mNext = 0; public CircularIterator(Distribution<T> pDist) { mDist = pDist; } @Override public boolean hasNext() { return mDist.getArray() != null && mDist.getArray().length > 0; } @Override public T next() { T oResult = null; synchronized (mLock) { oResult = mDist.get(mNext); mNext++; if (mNext >= mDist.size()) mNext = 0; } return oResult; } public void remove() { throw new RuntimeException("Not supported."); }; } private Random mRandom = new Random(); private int mSize; private int mFilledIn; private T[] mArray; private T mDefault; public Distribution(Class<T> pClass, int pSize) { this(pClass, null, pSize); } public Distribution(Class<T> pClass, T pDefault, int pSize) { mSize = pSize; mArray = (T[]) Array.newInstance(pClass, pSize); mDefault = pDefault; } public synchronized double fill(T pObject, double pProbability) { int oSampleSize = mSize - mFilledIn; double oProbabilityWithinRemainingSpots = pProbability * mSize / (double) oSampleSize; long oThreshold = Math.round( oSampleSize * (1.0 - oProbabilityWithinRemainingSpots) ); int oActualIterations = 0; int oFilledInCounter = 0; for (int i = 0; i < mArray.length; i++) { if (mArray[i] != null) continue; oActualIterations++; if (mRandom.nextInt(oSampleSize) >= oThreshold) { oFilledInCounter++; mArray[i] = pObject; } } mFilledIn += oFilledInCounter; //System.out.println( // ">> Sub-fill-in rate = " + (oFilledInCounter / (double) oSampleSize) * 100 + // ", Actual fill-in rate = " + (oFilledInCounter / (double) mSize) * 100); double oActulFillInRate = (oFilledInCounter / (double) mSize); return oActulFillInRate - pProbability; } public Iterator<T> getCircularIterator() { return new CircularIterator<T>(this); } protected T[] getArray() { return mArray; } public int size() { return mSize; } public T get(int pIndex) { return mArray[pIndex] == null ? mDefault : mArray[pIndex]; } }