Uploaded image for project: 'Commons Math'
  1. Commons Math
  2. MATH-1306

Add public void nextBytes(byte[] bytes, int position, int length) method into the RandomGenerator interface

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Resolved
    • Major
    • Resolution: Won't Fix
    • 3.5
    • None
    • None
    • None
    • Patch

    Description

      I propose to add public void nextBytes(byte[] bytes, int position, int length) method into the RandomGenerator interface.

      Rationality: to improve performance and memory usage in cases when one needs to fill only a specified region of a byte array. Today to do that you need to use a temporary byte array and copy it by yourself into the specified region of the destination byte array.

      I propose the following code, based on the code of BitsStreamGenerator commited in MATH-1305

      	@Override
      	public void nextBytes(byte[] bytes) {
      		nextBytesFill(bytes, 0, bytes.length);
      	}
      
      	// TODO add this method into RandomGenerator interface
      	//@Override
      	public void nextBytes(byte[] bytes, int position, int length) {
      		if (position < 0 || position > bytes.length - 1) {
      			throw new OutOfRangeException(LocalizedFormats.OUT_OF_RANGE_SIMPLE, position, 0, bytes.length - 1);
      		}
      		if (length < 0 || length > bytes.length - position) {
      			throw new OutOfRangeException(LocalizedFormats.OUT_OF_RANGE_SIMPLE, length, 0, bytes.length - position);
      		}
      
      		nextBytesFill(bytes, position, length);
      	}
      
      	private void nextBytesFill(byte[] bytes, int position, int length) {
      		int index = position;
      
      		// Position plus multiple 4 part of length (i.e. length with two least significant bits unset).
      		final int indexLoopLimit = position + (length & 0x7ffffffc);
      
      		// Start filling in the byte array, 4 bytes at a time.
      		while (index < indexLoopLimit) {
      			final int random = next(32);
      			bytes[index++] = (byte) random;
      			bytes[index++] = (byte) (random >>> 8);
      			bytes[index++] = (byte) (random >>> 16);
      			bytes[index++] = (byte) (random >>> 24);
      		}
      
      		final int indexLimit = position + length;
      		
      		// Fill in the remaining bytes.
      		if (index < indexLimit) {
      			int random = next(32);
      			while (true) {
      				bytes[index++] = (byte) random;
      				if (index < indexLimit) {
      					random >>>= 8;
      				} else {
      					break;
      				}
      			}
      		}
      	}
      

      Attachments

        1. MersenneTwister1305.java
          1.0 kB
          Rostislav Krasny
        2. MersenneTwister1306.java
          2 kB
          Rostislav Krasny

        Issue Links

          Activity

            People

              Unassigned Unassigned
              rosti.bsd Rostislav Krasny
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: