/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cassandra.stress.generate;
import java.util.Random;
import org.apache.commons.math3.random.RandomGenerator;
// based on http://en.wikipedia.org/wiki/Xorshift, but periodically we reseed with our stronger random generator
// note it is also non-atomically updated, so expects to be used by a single thread
public class FasterRandom implements RandomGenerator
{
final Random random = new Random();
private long seed;
private int reseed;
public void setSeed(int seed)
{
setSeed((long) seed);
}
public void setSeed(int[] ints)
{
if (ints.length > 1)
setSeed (((long) ints[0] << 32) | ints[1]);
else
setSeed(ints[0]);
}
public void setSeed(long seed)
{
this.seed = seed;
rollover();
}
private void rollover()
{
this.reseed = 0;
random.setSeed(seed);
seed = random.nextLong();
}
public void nextBytes(byte[] bytes)
{
int i = 0;
while (i < bytes.length)
{
long next = nextLong();
while (i < bytes.length)
{
bytes[i++] = (byte) (next & 0xFF);
next >>>= 8;
}
}
}
public int nextInt()
{
return (int) nextLong();
}
public int nextInt(int i)
{
return Math.abs((int) nextLong() % i);
}
public long nextLong()
{
if (++this.reseed == 32)
rollover();
long seed = this.seed;
seed ^= seed >> 12;
seed ^= seed << 25;
seed ^= seed >> 27;
this.seed = seed;
return seed * 2685821657736338717L;
}
public boolean nextBoolean()
{
return ((int) nextLong() & 1) == 1;
}
public float nextFloat()
{
return Float.intBitsToFloat((int) nextLong());
}
public double nextDouble()
{
return Double.longBitsToDouble(nextLong());
}
public double nextGaussian()
{
return random.nextGaussian();
}
}