Repository: commons-rng
Updated Branches:
  refs/heads/master ab5acabdc -> 65abc5dcf


RNG-58: Allow state to be stored at all levels of the class hierarchy.


Project: http://git-wip-us.apache.org/repos/asf/commons-rng/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-rng/commit/65abc5dc
Tree: http://git-wip-us.apache.org/repos/asf/commons-rng/tree/65abc5dc
Diff: http://git-wip-us.apache.org/repos/asf/commons-rng/diff/65abc5dc

Branch: refs/heads/master
Commit: 65abc5dcfe4198b4244d4083d790ea870edbebe5
Parents: ab5acab
Author: Gilles <[email protected]>
Authored: Fri Oct 5 00:15:51 2018 +0200
Committer: Gilles <[email protected]>
Committed: Fri Oct 5 00:15:51 2018 +0200

----------------------------------------------------------------------
 .../apache/commons/rng/core/BaseProvider.java   | 97 ++++++++++++++++++--
 .../commons/rng/core/source32/AbstractWell.java |  9 +-
 .../commons/rng/core/source32/ISAACRandom.java  |  9 +-
 .../commons/rng/core/source32/IntProvider.java  |  7 ++
 .../commons/rng/core/source32/JDKRandom.java    | 13 ++-
 .../commons/rng/core/source32/KISSRandom.java   | 10 +-
 .../rng/core/source32/MersenneTwister.java      |  9 +-
 .../rng/core/source32/MultiplyWithCarry256.java |  9 +-
 .../commons/rng/core/source64/LongProvider.java |  7 ++
 .../rng/core/source64/MersenneTwister64.java    |  9 +-
 .../commons/rng/core/source64/SplitMix64.java   |  8 +-
 .../commons/rng/core/source64/TwoCmres.java     |  9 +-
 .../rng/core/source64/XorShift1024Star.java     | 10 +-
 .../commons/rng/core/BaseProviderTest.java      |  9 +-
 .../rng/core/ProvidersCommonParametricTest.java |  2 +-
 15 files changed, 170 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/BaseProvider.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/BaseProvider.java 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/BaseProvider.java
index 3329d2d..334c43d 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/BaseProvider.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/BaseProvider.java
@@ -81,13 +81,87 @@ public abstract class BaseProvider
     }
 
     /**
+     * Combine parent and subclass states.
+     * This method must be called by all subclasses in order to ensure
+     * that state can be restored in case some of it is stored higher
+     * up in the class hierarchy.
+     *
+     * I.e. the body of the overridden {@link #getStateInternal()},
+     * will end with a statement like the following:
+     * <pre>
+     *  <code>
+     *    return composeStateInternal(super.getStateInternal(),
+     *                                state);
+     *  </code>
+     * </pre>
+     * where {@code state} is the state needed and defined by the class
+     * where the method is overridden.
+     *
+     * @param parentState State of the calling class' parent.
+     * @param state State of the calling class.
+     * @return the combined state.
+     * Bytes that belong to the local state will be stored at the
+     * beginning of the resulting array.
+     */
+    protected byte[] composeStateInternal(byte[] state,
+                                          byte[] parentState) {
+        if (parentState == null) {
+            return state;
+        }
+
+        final int len = parentState.length + state.length;
+        final byte[] c = new byte[len];
+        System.arraycopy(state, 0, c, 0, state.length);
+        System.arraycopy(parentState, 0, c, state.length, parentState.length);
+        return c;
+    }
+
+    /**
+     * Splits the given {@code state} into a part to be consumed by the caller
+     * in order to restore its local state, while the reminder is passed to
+     * the parent class.
+     *
+     * I.e. the body of the overridden {@link #setStateInternal(byte[])},
+     * will contain statements like the following:
+     * <pre>
+     *  <code>
+     *    final byte[][] s = splitState(state, localStateLength);
+     *    // Use "s[0]" to recover the local state.
+     *    super.setStateInternal(s[1]);
+     *  </code>
+     * </pre>
+     * where {@code state} is the combined state of the calling class and of
+     * all its parents.
+     *
+     * @param state State.
+     * The local state must be stored at the beginning of the array.
+     * @param localStateLength Number of elements that will be consumed by the
+     * locally defined state.
+     * @return the local state (in slot 0) and the parent state (in slot 1).
+     * @throws IllegalStateException if {@code state.length < 
localStateLength}.
+     */
+    protected byte[][] splitStateInternal(byte[] state,
+                                          int localStateLength) {
+        checkStateSize(state, localStateLength);
+
+        final byte[] local = new byte[localStateLength];
+        System.arraycopy(state, 0, local, 0, localStateLength);
+        final int parentLength = state.length - localStateLength;
+        final byte[] parent = new byte[parentLength];
+        System.arraycopy(state, localStateLength, parent, 0, parentLength);
+
+        return new byte[][] { local, parent };
+    }
+
+    /**
      * Creates a snapshot of the RNG state.
      *
      * @return the internal state.
-     * @throws UnsupportedOperationException if not implemented.
      */
     protected byte[] getStateInternal() {
-        throw new UnsupportedOperationException();
+        // This class has no state (and is the top-level class that
+        // declares this method).
+        return new byte[0];
     }
 
     /**
@@ -95,12 +169,16 @@ public abstract class BaseProvider
      *
      * @param state State (previously obtained by a call to
      * {@link #getStateInternal()}).
-     * @throws UnsupportedOperationException if not implemented.
+     * @throws IllegalStateException if the size of the given array is
+     * not consistent with the state defined by this class.
      *
      * @see #checkStateSize(byte[],int)
      */
     protected void setStateInternal(byte[] state) {
-        throw new UnsupportedOperationException();
+        if (state.length != 0) {
+            // This class has no state.
+            throw new IllegalStateException("State not fully recovered by 
subclasses");
+        }
     }
 
     /**
@@ -170,13 +248,16 @@ public abstract class BaseProvider
      *
      * @param state State.
      * @param expected Expected length of {@code state} array.
-     * @throws IllegalArgumentException if {@code state.length != expected}.
+     * @throws IllegalStateException if {@code state.length < expected}.
+     * @deprecated Method is used internally and should be made private in
+     * some future release.
      */
+    @Deprecated
     protected void checkStateSize(byte[] state,
                                   int expected) {
-        if (state.length != expected) {
-            throw new IllegalArgumentException("State size must be " + 
expected +
-                                               " but was " + state.length);
+        if (state.length < expected) {
+            throw new IllegalStateException("State size must be larger than " +
+                                            expected + " but was " + 
state.length);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/AbstractWell.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/AbstractWell.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/AbstractWell.java
index b181f30..c8f57c8 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/AbstractWell.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/AbstractWell.java
@@ -67,17 +67,20 @@ public abstract class AbstractWell extends IntProvider {
         final int[] s = Arrays.copyOf(v, v.length + 1);
         s[v.length] = index;
 
-        return NumberFactory.makeByteArray(s);
+        return composeStateInternal(super.getStateInternal(),
+                                    NumberFactory.makeByteArray(s));
     }
 
     /** {@inheritDoc} */
     @Override
     protected void setStateInternal(byte[] s) {
-        checkStateSize(s, (v.length + 1) * 4);
+        final byte[][] c = splitStateInternal(s, (v.length + 1) * 4);
 
-        final int[] tmp = NumberFactory.makeIntArray(s);
+        final int[] tmp = NumberFactory.makeIntArray(c[0]);
         System.arraycopy(tmp, 0, v, 0, v.length);
         index = tmp[v.length];
+
+        super.setStateInternal(c[1]);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/ISAACRandom.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/ISAACRandom.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/ISAACRandom.java
index 597d1f0..51cfd15 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/ISAACRandom.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/ISAACRandom.java
@@ -94,15 +94,16 @@ public class ISAACRandom extends IntProvider {
         System.arraycopy(sMem, 0, s, SIZE, SIZE);
         System.arraycopy(sRem, 0, s, 2 * SIZE, sRem.length);
 
-        return NumberFactory.makeByteArray(s);
+        return composeStateInternal(super.getStateInternal(),
+                                    NumberFactory.makeByteArray(s));
     }
 
     /** {@inheritDoc} */
     @Override
     protected void setStateInternal(byte[] s) {
-        checkStateSize(s, (2 * SIZE + 4) * 4);
+        final byte[][] c = splitStateInternal(s, (2 * SIZE + 4) * 4);
 
-        final int[] tmp = NumberFactory.makeIntArray(s);
+        final int[] tmp = NumberFactory.makeIntArray(c[0]);
         System.arraycopy(tmp, 0, rsl, 0, SIZE);
         System.arraycopy(tmp, SIZE, mem, 0, SIZE);
         final int offset = 2 * SIZE;
@@ -110,6 +111,8 @@ public class ISAACRandom extends IntProvider {
         isaacA = tmp[offset + 1];
         isaacB = tmp[offset + 2];
         isaacC = tmp[offset + 3];
+
+        super.setStateInternal(c[1]);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/IntProvider.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/IntProvider.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/IntProvider.java
index f4a9846..ac07e02 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/IntProvider.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/IntProvider.java
@@ -30,6 +30,13 @@ public abstract class IntProvider
 
     /** {@inheritDoc} */
     @Override
+    protected byte[] getStateInternal() {
+        return composeStateInternal(super.getStateInternal(),
+                                    new byte[0]); // No local state.
+    }
+
+    /** {@inheritDoc} */
+    @Override
     public int nextInt() {
         return next();
     }

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/JDKRandom.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/JDKRandom.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/JDKRandom.java
index 1312814..d010e5b 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/JDKRandom.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/JDKRandom.java
@@ -42,6 +42,8 @@ import java.io.ByteArrayInputStream;
 public class JDKRandom extends IntProvider {
     /** Delegate.  Cannot be "final" (to allow serialization). */
     private Random delegate;
+    /** Size of the byte representation of the state (of the delegate). */
+    private int stateSize;
 
     /**
      * Creates an instance with the given seed.
@@ -72,7 +74,10 @@ public class JDKRandom extends IntProvider {
             // Serialize the "delegate".
             oos.writeObject(delegate);
 
-            return bos.toByteArray();
+            final byte[] state = bos.toByteArray();
+            stateSize = state.length; // To allow state recovery.
+            return composeStateInternal(super.getStateInternal(),
+                                        state);
         } catch (IOException e) {
             // Workaround checked exception.
             throw new IllegalStateException(e);
@@ -82,8 +87,10 @@ public class JDKRandom extends IntProvider {
     /** {@inheritDoc} */
     @Override
     protected void setStateInternal(byte[] s) {
+        final byte[][] c = splitStateInternal(s, stateSize);
+
         try {
-            final ByteArrayInputStream bis = new ByteArrayInputStream(s);
+            final ByteArrayInputStream bis = new ByteArrayInputStream(c[0]);
             final ObjectInputStream ois = new ObjectInputStream(bis);
 
             delegate = (Random) ois.readObject();
@@ -94,5 +101,7 @@ public class JDKRandom extends IntProvider {
             // Workaround checked exception.
             throw new IllegalStateException(e);
         }
+
+        super.setStateInternal(c[1]);
     }
 }

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/KISSRandom.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/KISSRandom.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/KISSRandom.java
index 24a9d3c..c50d8f0 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/KISSRandom.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/KISSRandom.java
@@ -55,20 +55,22 @@ public class KISSRandom extends IntProvider {
     /** {@inheritDoc} */
     @Override
     protected byte[] getStateInternal() {
-        return NumberFactory.makeByteArray(new int[] { z, w, jsr, jcong });
+        return composeStateInternal(super.getStateInternal(),
+                                    NumberFactory.makeByteArray(new int[] { z, 
w, jsr, jcong }));
     }
 
     /** {@inheritDoc} */
     @Override
     protected void setStateInternal(byte[] s) {
-        checkStateSize(s, SEED_SIZE * 4);
-
-        final int[] tmp = NumberFactory.makeIntArray(s);
+        final byte[][] c = splitStateInternal(s, SEED_SIZE * 4);
 
+        final int[] tmp = NumberFactory.makeIntArray(c[0]);
         z = tmp[0];
         w = tmp[1];
         jsr = tmp[2];
         jcong = tmp[3];
+
+        super.setStateInternal(c[1]);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/MersenneTwister.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/MersenneTwister.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/MersenneTwister.java
index 34277c6..f1a8727 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/MersenneTwister.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/MersenneTwister.java
@@ -122,17 +122,20 @@ public class MersenneTwister extends IntProvider {
         final int[] s = Arrays.copyOf(mt, N + 1);
         s[N] = mti;
 
-        return NumberFactory.makeByteArray(s);
+        return composeStateInternal(super.getStateInternal(),
+                                    NumberFactory.makeByteArray(s));
     }
 
     /** {@inheritDoc} */
     @Override
     protected void setStateInternal(byte[] s) {
-        checkStateSize(s, (N + 1) * 4);
+        final byte[][] c = splitStateInternal(s, (N + 1) * 4);
 
-        final int[] tmp = NumberFactory.makeIntArray(s);
+        final int[] tmp = NumberFactory.makeIntArray(c[0]);
         System.arraycopy(tmp, 0, mt, 0, N);
         mti = tmp[N];
+
+        super.setStateInternal(c[1]);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/MultiplyWithCarry256.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/MultiplyWithCarry256.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/MultiplyWithCarry256.java
index f0714e1..28996aa 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/MultiplyWithCarry256.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source32/MultiplyWithCarry256.java
@@ -65,19 +65,22 @@ public class MultiplyWithCarry256 extends IntProvider {
         s[SEED_SIZE - 1] = carry;
         s[SEED_SIZE] = index;
 
-        return NumberFactory.makeByteArray(s);
+        return composeStateInternal(super.getStateInternal(),
+                                    NumberFactory.makeByteArray(s));
     }
 
     /** {@inheritDoc} */
     @Override
     protected void setStateInternal(byte[] s) {
-        checkStateSize(s, (SEED_SIZE + 1) * 4);
+        final byte[][] c = splitStateInternal(s, (SEED_SIZE + 1) * 4);
 
-        final int[] tmp = NumberFactory.makeIntArray(s);
+        final int[] tmp = NumberFactory.makeIntArray(c[0]);
 
         System.arraycopy(tmp, 0, state, 0, Q_SIZE);
         carry = tmp[SEED_SIZE - 1];
         index = tmp[SEED_SIZE];
+
+        super.setStateInternal(c[1]);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/LongProvider.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/LongProvider.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/LongProvider.java
index 93982e5..ca5903d 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/LongProvider.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/LongProvider.java
@@ -30,6 +30,13 @@ public abstract class LongProvider
 
     /** {@inheritDoc} */
     @Override
+    protected byte[] getStateInternal() {
+        return composeStateInternal(super.getStateInternal(),
+                                    new byte[0]); // No local state.
+    }
+
+    /** {@inheritDoc} */
+    @Override
     public long nextLong() {
         return next();
     }

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/MersenneTwister64.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/MersenneTwister64.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/MersenneTwister64.java
index bd0683f..17996b9 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/MersenneTwister64.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/MersenneTwister64.java
@@ -102,17 +102,20 @@ public class MersenneTwister64 extends LongProvider {
         final long[] s = Arrays.copyOf(mt, NN + 1);
         s[NN] = mti;
 
-        return NumberFactory.makeByteArray(s);
+        return composeStateInternal(super.getStateInternal(),
+                                    NumberFactory.makeByteArray(s));
     }
 
     /** {@inheritDoc} */
     @Override
     protected void setStateInternal(byte[] s) {
-        checkStateSize(s, (NN + 1) * 8);
+        final byte[][] c = splitStateInternal(s, (NN + 1) * 8);
 
-        final long[] tmp = NumberFactory.makeLongArray(s);
+        final long[] tmp = NumberFactory.makeLongArray(c[0]);
         System.arraycopy(tmp, 0, mt, 0, NN);
         mti = (int) tmp[NN];
+
+        super.setStateInternal(c[1]);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/SplitMix64.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/SplitMix64.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/SplitMix64.java
index 79af46f..eb1861b 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/SplitMix64.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/SplitMix64.java
@@ -62,14 +62,16 @@ public class SplitMix64 extends LongProvider {
     /** {@inheritDoc} */
     @Override
     protected byte[] getStateInternal() {
-        return NumberFactory.makeByteArray(state);
+        return composeStateInternal(super.getStateInternal(),
+                                    NumberFactory.makeByteArray(state));
     }
 
     /** {@inheritDoc} */
     @Override
     protected void setStateInternal(byte[] s) {
-        checkStateSize(s, 8);
+        final byte[][] c = splitStateInternal(s, 8);
 
-        state = NumberFactory.makeLong(s);
+        state = NumberFactory.makeLong(c[0]);
+        super.setStateInternal(c[1]);
     }
 }

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/TwoCmres.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/TwoCmres.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/TwoCmres.java
index b542d0b..7d052ba 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/TwoCmres.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/TwoCmres.java
@@ -119,17 +119,20 @@ public class TwoCmres extends LongProvider {
     /** {@inheritDoc} */
     @Override
     protected byte[] getStateInternal() {
-        return NumberFactory.makeByteArray(new long[] { xx, yy });
+        return composeStateInternal(super.getStateInternal(),
+                                    NumberFactory.makeByteArray(new long[] { 
xx, yy }));
     }
 
     /** {@inheritDoc} */
     @Override
     protected void setStateInternal(byte[] s) {
-        checkStateSize(s, 16);
+        final byte[][] c = splitStateInternal(s, 16);
 
-        final long[] state = NumberFactory.makeLongArray(s);
+        final long[] state = NumberFactory.makeLongArray(c[0]);
         xx = state[0];
         yy = state[1];
+
+        super.setStateInternal(c[1]);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024Star.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024Star.java
 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024Star.java
index 1877453..af230a9 100644
--- 
a/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024Star.java
+++ 
b/commons-rng-core/src/main/java/org/apache/commons/rng/core/source64/XorShift1024Star.java
@@ -55,18 +55,20 @@ public class XorShift1024Star extends LongProvider {
         final long[] s = Arrays.copyOf(state, SEED_SIZE + 1);
         s[SEED_SIZE] = index;
 
-        return NumberFactory.makeByteArray(s);
+        return composeStateInternal(super.getStateInternal(),
+                                    NumberFactory.makeByteArray(s));
     }
 
     /** {@inheritDoc} */
     @Override
     protected void setStateInternal(byte[] s) {
-        checkStateSize(s, (SEED_SIZE + 1) * 8);
-
-        final long[] tmp = NumberFactory.makeLongArray(s);
+        final byte[][] c = splitStateInternal(s, (SEED_SIZE + 1) * 8);
 
+        final long[] tmp = NumberFactory.makeLongArray(c[0]);
         System.arraycopy(tmp, 0, state, 0, SEED_SIZE);
         index = (int) tmp[SEED_SIZE];
+
+        super.setStateInternal(c[1]);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/test/java/org/apache/commons/rng/core/BaseProviderTest.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/test/java/org/apache/commons/rng/core/BaseProviderTest.java
 
b/commons-rng-core/src/test/java/org/apache/commons/rng/core/BaseProviderTest.java
index 6fc9ed2..2e316ac 100644
--- 
a/commons-rng-core/src/test/java/org/apache/commons/rng/core/BaseProviderTest.java
+++ 
b/commons-rng-core/src/test/java/org/apache/commons/rng/core/BaseProviderTest.java
@@ -28,13 +28,8 @@ import org.junit.Assert;
  * tests too).
  */
 public class BaseProviderTest {
-    @Test(expected=UnsupportedOperationException.class)
-    public void testMissingGetStateInternal() {
-        new DummyGenerator().saveState();
-    }
-
-    @Test(expected=UnsupportedOperationException.class)
-    public void testMissingSetStateInternal() {
+    @Test(expected=IllegalStateException.class)
+    public void testWrongStateSize() {
         new DummyGenerator().restoreState(new RandomProviderDefaultState(new 
byte[1]));
     }
 

http://git-wip-us.apache.org/repos/asf/commons-rng/blob/65abc5dc/commons-rng-core/src/test/java/org/apache/commons/rng/core/ProvidersCommonParametricTest.java
----------------------------------------------------------------------
diff --git 
a/commons-rng-core/src/test/java/org/apache/commons/rng/core/ProvidersCommonParametricTest.java
 
b/commons-rng-core/src/test/java/org/apache/commons/rng/core/ProvidersCommonParametricTest.java
index 6e27c15..922e9c9 100644
--- 
a/commons-rng-core/src/test/java/org/apache/commons/rng/core/ProvidersCommonParametricTest.java
+++ 
b/commons-rng-core/src/test/java/org/apache/commons/rng/core/ProvidersCommonParametricTest.java
@@ -252,7 +252,7 @@ public class ProvidersCommonParametricTest {
         Assert.assertTrue(listOrig.equals(listReplay));
     }
 
-    @Test(expected=IllegalArgumentException.class)
+    @Test(expected=IllegalStateException.class)
     public void testStateWrongSize() {
         // We don't know what is the state of "java.lang.Random": skipping.
         Assume.assumeTrue(generator.toString().indexOf("JDKRandom") == -1);

Reply via email to