Skip to content

Commit

Permalink
Merge branch 'MersenneTwister'
Browse files Browse the repository at this point in the history
Conflicts:
	src/org/jruby/Ruby.java
	src/org/jruby/RubyArray.java
	src/org/jruby/RubyRandom.java
	src/org/jruby/util/TypeConverter.java
  • Loading branch information
Hiroshi Nakamura committed May 11, 2011
2 parents 7837c84 + fd957a1 commit 8c6dba0
Show file tree
Hide file tree
Showing 8 changed files with 649 additions and 372 deletions.
52 changes: 20 additions & 32 deletions src/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
import java.util.Vector;
Expand Down Expand Up @@ -128,7 +127,6 @@
import java.nio.channels.ClosedChannelException;
import java.util.EnumSet;
import java.util.concurrent.atomic.AtomicLong;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.RubyInstanceConfig.CompileMode;
import org.jruby.ast.RootNode;
import org.jruby.ast.executable.RuntimeCache;
Expand Down Expand Up @@ -1157,10 +1155,6 @@ private void initCore() {

encodingService = new EncodingService(this);

if (is1_9()) {
RubyRandom.createRandomClass(this);
}

RubySymbol.createSymbolClass(this);

if (profile.allowClass("ThreadGroup")) {
Expand Down Expand Up @@ -1209,6 +1203,12 @@ private void initCore() {
}
if (profile.allowClass("Bignum")) {
RubyBignum.createBignumClass(this);
// RubyRandom depends on Bignum existence.
if (is1_9()) {
RubyRandom.createRandomClass(this);
} else {
setDefaultRand(new RubyRandom.RandomType(this));
}
}
ioClass = RubyIO.createIOClass(this);

Expand Down Expand Up @@ -1921,7 +1921,14 @@ public RubyClass getStructClass() {
}
void setStructClass(RubyClass structClass) {
this.structClass = structClass;
}
}

public RubyClass getRandomClass() {
return randomClass;
}
void setRandomClass(RubyClass randomClass) {
this.randomClass = randomClass;
}

public IRubyObject getTmsStruct() {
return tmsStruct;
Expand Down Expand Up @@ -2159,12 +2166,13 @@ public RubyClass getInvalidByteSequenceError() {
return invalidByteSequenceError;
}

public RubyClass getRandomClass() {
return randomClass;
private RubyRandom.RandomType defaultRand;
public RubyRandom.RandomType getDefaultRand() {
return defaultRand;
}

public void setRandomClass(RubyClass randomClass) {
this.randomClass = randomClass;
public void setDefaultRand(RubyRandom.RandomType defaultRand) {
this.defaultRand = defaultRand;
}

private RubyHash charsetMap;
Expand Down Expand Up @@ -3320,18 +3328,6 @@ public RubySymbol.SymbolTable getSymbolTable() {
return symbolTable;
}

public void setRandomSeed(long randomSeed) {
this.randomSeed = randomSeed;
}

public long getRandomSeed() {
return randomSeed;
}

public Random getRandom() {
return random;
}

public ObjectSpace getObjectSpace() {
return objectSpace;
}
Expand Down Expand Up @@ -3385,10 +3381,6 @@ public ChannelDescriptor getDescriptorByFileno(int aFileno) {
return ChannelDescriptor.getDescriptorByFileno(aFileno);
}

public long incrementRandomSeedSequence() {
return randomSeedSequence++;
}

public InputStream getIn() {
return in;
}
Expand Down Expand Up @@ -3875,10 +3867,6 @@ public boolean isBooting() {

private final RubySymbol.SymbolTable symbolTable = new RubySymbol.SymbolTable(this);

private long randomSeed = 0;
private long randomSeedSequence = 0;
private Random random = new Random();

private final List<EventHook> eventHooks = new Vector<EventHook>();
private boolean hasEventHooks;
private boolean globalAbortOnExceptionEnabled = false;
Expand Down
110 changes: 17 additions & 93 deletions src/org/jruby/RubyArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -3638,21 +3638,19 @@ public IRubyObject choice(ThreadContext context) {
if (realLength == 0) {
return context.nil;
}
return eltOk(begin + context.runtime.getRandom().nextInt(realLength));
return eltOk((int) (context.runtime.getDefaultRand().genrandReal() * realLength));
}

@JRubyMethod(name = "shuffle!", compat = RUBY1_8)
public IRubyObject shuffle_bang(ThreadContext context) {
modify();
Random random = context.getRuntime().getRandom();

int i = realLength;

try {
while (i > 0) {
int r = random.nextInt(i);
IRubyObject tmp = values[begin + --i];
values[begin + i] = values[begin + r];
int r = (int)(context.runtime.getDefaultRand().genrandReal() * i);
IRubyObject tmp = eltOk(--i);
values[begin + i] = eltOk(r);
values[begin + r] = tmp;
}
} catch (ArrayIndexOutOfBoundsException e) {
Expand All @@ -3673,12 +3671,11 @@ public IRubyObject shuffle_bang(ThreadContext context, IRubyObject[] args) {
}
}
int i = realLength;

try {
while (i > 0) {
int r = randomReal(context, randgen, i);
IRubyObject tmp = values[begin + --i];
values[begin + i] = values[begin + r];
int r = (int) (RubyRandom.randomReal(context, randgen) * i);
IRubyObject tmp = eltOk(--i);
values[begin + i] = eltOk(r);
values[begin + r] = tmp;
}
} catch (ArrayIndexOutOfBoundsException e) {
Expand Down Expand Up @@ -3711,7 +3708,7 @@ public IRubyObject sample(ThreadContext context, IRubyObject[] args) {
if (realLength == 0)
return context.nil;
int i = realLength == 1 ? 0 : randomReal(context, randgen, realLength);
return values[begin + i];
return eltOk(i);
}
if (args.length > 0) {
IRubyObject hash = TypeConverter.checkHashType(context.runtime,
Expand All @@ -3727,9 +3724,9 @@ public IRubyObject sample(ThreadContext context, IRubyObject[] args) {
if (realLength == 0) {
return context.nil;
} else if (realLength == 1) {
return values[0];
return eltOk(0);
}
return values[randomReal(context, randgen, realLength)];
return eltOk(randomReal(context, randgen, realLength));
}
Ruby runtime = context.getRuntime();
int n = RubyNumeric.num2int(args[0]);
Expand All @@ -3753,13 +3750,13 @@ public IRubyObject sample(ThreadContext context, IRubyObject[] args) {
if (realLength <= 0)
return newEmptyArray(runtime);

return newArray(runtime, values[begin + (int) (rnds[0] * realLength)]);
return newArray(runtime, eltOk((int) (rnds[0] * realLength)));
case 2:
i = (int) (rnds[0] * realLength);
j = (int) (rnds[1] * (realLength - 1));
if (j >= i)
j++;
return newArray(runtime, values[begin + i], values[begin + j]);
return newArray(runtime, eltOk(i), eltOk(j));
case 3:
i = (int) (rnds[0] * realLength);
j = (int) (rnds[1] * (realLength - 1));
Expand All @@ -3772,8 +3769,8 @@ public IRubyObject sample(ThreadContext context, IRubyObject[] args) {
}
if (k >= l && (++k >= g))
++k;
return new RubyArray(runtime, new IRubyObject[] { values[begin + i],
values[begin + j], values[begin + k] });
return new RubyArray(runtime, new IRubyObject[] { eltOk(i),
eltOk(j), eltOk(k) });
}

int len = realLength;
Expand All @@ -3795,7 +3792,7 @@ public IRubyObject sample(ThreadContext context, IRubyObject[] args) {
}
IRubyObject[] result = new IRubyObject[n];
for (i = 0; i < n; i++)
result[i] = values[begin + idx[i]];
result[i] = eltOk(idx[i]);
return new RubyArray(runtime, result);
} else {
IRubyObject[] result = new IRubyObject[len];
Expand All @@ -3815,84 +3812,11 @@ public IRubyObject sample(ThreadContext context, IRubyObject[] args) {
return this; // not reached
}
}

@JRubyMethod(name = "sample", compat = RUBY1_9)
public IRubyObject sample(ThreadContext context, IRubyObject nv) {
Ruby runtime = context.getRuntime();
Random random = runtime.getRandom();
int n = RubyNumeric.num2int(nv);

if (n < 0) throw runtime.newArgumentError("negative sample number");
if (n > realLength) n = realLength;

int i, j, k;
try {
switch (n) {
case 0:
return newEmptyArray(runtime);
case 1:
if (realLength <= 0) return newEmptyArray(runtime);

return newArray(runtime, values[begin + random.nextInt(realLength)]);
case 2:
i = random.nextInt(realLength);
j = random.nextInt(realLength - 1);
if (j >= i) j++;
return newArray(runtime, values[begin + i], values[begin + j]);
case 3:
i = random.nextInt(realLength);
j = random.nextInt(realLength - 1);
k = random.nextInt(realLength - 2);
int l = j, g = i;
if (j >= i) {
l = i;
g = ++j;
}
if (k >= l && (++k >= g)) ++k;
return new RubyArray(runtime, new IRubyObject[] {values[begin + i], values[begin + j], values[begin + k]});
}

int len = realLength;
if (n > len) n = len;
if (n < SORTED_THRESHOLD) {
int idx[] = new int[SORTED_THRESHOLD];
int sorted[] = new int[SORTED_THRESHOLD];
sorted[0] = idx[0] = random.nextInt(len);
for (i = 1; i < n; i++) {
k = random.nextInt(--len);
for (j = 0; j < i; j++) {
if (k < sorted[j]) break;
k++;
}
System.arraycopy(sorted, j, sorted, j + 1, i - j);
sorted[j] = idx[i] = k;
}
IRubyObject[]result = new IRubyObject[n];
for (i = 0; i < n; i++) result[i] = values[begin + idx[i]];
return new RubyArray(runtime, result);
} else {
IRubyObject[]result = new IRubyObject[len];
System.arraycopy(values, begin, result, 0, len);
for (i = 0; i < n; i++) {
j = random.nextInt(len - i) + i;
IRubyObject tmp = result[j];
result[j] = result[i];
result[i] = tmp;
}
RubyArray ary = new RubyArray(runtime, result);
ary.realLength = n;
return ary;
}
} catch (ArrayIndexOutOfBoundsException aioob) {
concurrentModification();
return this; // not reached
}
}

private int randomReal(ThreadContext context, IRubyObject randgen, int len) {
return (int) (RubyRandom.randomReal(context, randgen) * len);
}

private static void aryReverse(IRubyObject[] _p1, int p1, IRubyObject[] _p2, int p2) {
while(p1 < p2) {
IRubyObject tmp = _p1[p1];
Expand Down
7 changes: 0 additions & 7 deletions src/org/jruby/RubyBasicObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -795,13 +795,6 @@ public IRubyObject checkArrayType() {
return TypeConverter.convertToTypeWithCheck(this, getRuntime().getArray(), "to_ary");
}

// 1.9 rb_check_to_integer
IRubyObject checkIntegerType(Ruby runtime, IRubyObject obj, String method) {
if (obj instanceof RubyFixnum) return obj;
IRubyObject conv = TypeConverter.convertToType(obj, getRuntime().getInteger(), method, false);
return conv instanceof RubyInteger ? conv : obj.getRuntime().getNil();
}

/**
* @see IRubyObject.toJava
*/
Expand Down
Loading

0 comments on commit 8c6dba0

Please sign in to comment.