/*
* Distributor.java
*
* Copyright (C) 2008 Pei Wang
*
* This file is part of Open-NARS.
*
* Open-NARS is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Open-NARS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Open-NARS. If not, see <http://www.gnu.org/licenses/>.
*/
package nars.storage;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* A pseudo-random number generator, used in Bag.
*/
public final class Distributor {
/** Shuffled sequence of index numbers */
public final short order[];
/** Capacity of the array */
public final int capacity;
private final static Map<Integer,Distributor> distributors = new HashMap(8);
public static Distributor get(int range) {
Distributor d = distributors.get(range);
if (d==null) {
d = new Distributor(range);
distributors.put(range, d);
}
return d;
}
/**
* For any number N < range, there is N+1 copies of it in the array, distributed as evenly as possible
* @param range Range of valid numbers
*/
protected Distributor(final int range) {
int index, rank, time;
capacity = (range * (range + 1)) / 2;
order = new short[capacity];
Arrays.fill(order, (short)-1);
index = capacity;
for (rank = range; rank > 0; rank--) {
final int capDivRank = capacity / rank;
for (time = 0; time < rank; time++) {
index = (capDivRank + index) % capacity;
while (order[index] >= 0) {
index = (index + 1) % capacity;
}
order[index] = (short)(rank - 1);
}
}
}
/**
* Get the next number according to the given index
* @param index The current index
* @return the random value
*/
public final short pick(final int index) {
return order[index];
}
/**
* Advance the index
* @param index The current index
* @return the next index
*/
public final int next(final int index) {
return (index + 1) % capacity;
}
}