You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2012/07/21 21:26:46 UTC

svn commit: r1364157 [2/3] - in /lucene/dev/branches/pforcodec_3892/lucene/core/src: java/org/apache/lucene/util/packed/ test/org/apache/lucene/util/packed/

Modified: lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/util/packed/BulkOperation.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/util/packed/BulkOperation.java?rev=1364157&r1=1364156&r2=1364157&view=diff
==============================================================================
--- lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/util/packed/BulkOperation.java (original)
+++ lucene/dev/branches/pforcodec_3892/lucene/core/src/java/org/apache/lucene/util/packed/BulkOperation.java Sat Jul 21 19:26:45 2012
@@ -19,12 +19,14 @@ package org.apache.lucene.util.packed;
  * limitations under the License.
  */
 
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
 import java.util.EnumMap;
 
 /**
  * Efficient sequential read/write of packed integers.
  */
-abstract class BulkOperation {
+abstract class BulkOperation implements PackedInts.Decoder, PackedInts.Encoder {
 
   static final EnumMap<PackedInts.Format, BulkOperation[]> BULK_OPERATIONS = new EnumMap<PackedInts.Format, BulkOperation[]>(PackedInts.Format.class);
 
@@ -68,28 +70,9 @@ abstract class BulkOperation {
     }
   }
 
-  /**
-   * The minimum number of blocks required to perform a bulk get/set.
-   */
-  public abstract int blocks();
-
-  /**
-   * The number of values that can be stored in <code>blocks()</code> blocks.
-   */
-  public abstract int values();
-
-  /**
-   * Get <code>n * values()</code> values from <code>n * blocks()</code> blocks.
-   */
-  public abstract void get(long[] blocks, int blockIndex, long[] values, int valuesIndex, int iterations);
-
-  /**
-   * Set <code>n * values()</code> values into <code>n * blocks()</code> blocks.
-   */
-  public abstract void set(long[] blocks, int blockIndex, long[] values, int valuesIndex, int iterations);
-
   static {
-    BULK_OPERATIONS.put(PackedInts.Format.PACKED, new BulkOperation[65]);    BULK_OPERATIONS.get(PackedInts.Format.PACKED)[1] = new Packed64BulkOperation1();
+    BULK_OPERATIONS.put(PackedInts.Format.PACKED, new BulkOperation[65]);
+    BULK_OPERATIONS.get(PackedInts.Format.PACKED)[1] = new Packed64BulkOperation1();
     BULK_OPERATIONS.get(PackedInts.Format.PACKED)[2] = new Packed64BulkOperation2();
     BULK_OPERATIONS.get(PackedInts.Format.PACKED)[3] = new Packed64BulkOperation3();
     BULK_OPERATIONS.get(PackedInts.Format.PACKED)[4] = new Packed64BulkOperation4();
@@ -179,87 +162,167 @@ abstract class BulkOperation {
       return 64;
     }
 
-    public void get(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
-      for (int i = 0; i < iterations; ++i) {
-        final long block0 = blocks[bi++];
-        values[vi++] = block0 >>> 63;
-        values[vi++] = (block0 >>> 62) & 1L;
-        values[vi++] = (block0 >>> 61) & 1L;
-        values[vi++] = (block0 >>> 60) & 1L;
-        values[vi++] = (block0 >>> 59) & 1L;
-        values[vi++] = (block0 >>> 58) & 1L;
-        values[vi++] = (block0 >>> 57) & 1L;
-        values[vi++] = (block0 >>> 56) & 1L;
-        values[vi++] = (block0 >>> 55) & 1L;
-        values[vi++] = (block0 >>> 54) & 1L;
-        values[vi++] = (block0 >>> 53) & 1L;
-        values[vi++] = (block0 >>> 52) & 1L;
-        values[vi++] = (block0 >>> 51) & 1L;
-        values[vi++] = (block0 >>> 50) & 1L;
-        values[vi++] = (block0 >>> 49) & 1L;
-        values[vi++] = (block0 >>> 48) & 1L;
-        values[vi++] = (block0 >>> 47) & 1L;
-        values[vi++] = (block0 >>> 46) & 1L;
-        values[vi++] = (block0 >>> 45) & 1L;
-        values[vi++] = (block0 >>> 44) & 1L;
-        values[vi++] = (block0 >>> 43) & 1L;
-        values[vi++] = (block0 >>> 42) & 1L;
-        values[vi++] = (block0 >>> 41) & 1L;
-        values[vi++] = (block0 >>> 40) & 1L;
-        values[vi++] = (block0 >>> 39) & 1L;
-        values[vi++] = (block0 >>> 38) & 1L;
-        values[vi++] = (block0 >>> 37) & 1L;
-        values[vi++] = (block0 >>> 36) & 1L;
-        values[vi++] = (block0 >>> 35) & 1L;
-        values[vi++] = (block0 >>> 34) & 1L;
-        values[vi++] = (block0 >>> 33) & 1L;
-        values[vi++] = (block0 >>> 32) & 1L;
-        values[vi++] = (block0 >>> 31) & 1L;
-        values[vi++] = (block0 >>> 30) & 1L;
-        values[vi++] = (block0 >>> 29) & 1L;
-        values[vi++] = (block0 >>> 28) & 1L;
-        values[vi++] = (block0 >>> 27) & 1L;
-        values[vi++] = (block0 >>> 26) & 1L;
-        values[vi++] = (block0 >>> 25) & 1L;
-        values[vi++] = (block0 >>> 24) & 1L;
-        values[vi++] = (block0 >>> 23) & 1L;
-        values[vi++] = (block0 >>> 22) & 1L;
-        values[vi++] = (block0 >>> 21) & 1L;
-        values[vi++] = (block0 >>> 20) & 1L;
-        values[vi++] = (block0 >>> 19) & 1L;
-        values[vi++] = (block0 >>> 18) & 1L;
-        values[vi++] = (block0 >>> 17) & 1L;
-        values[vi++] = (block0 >>> 16) & 1L;
-        values[vi++] = (block0 >>> 15) & 1L;
-        values[vi++] = (block0 >>> 14) & 1L;
-        values[vi++] = (block0 >>> 13) & 1L;
-        values[vi++] = (block0 >>> 12) & 1L;
-        values[vi++] = (block0 >>> 11) & 1L;
-        values[vi++] = (block0 >>> 10) & 1L;
-        values[vi++] = (block0 >>> 9) & 1L;
-        values[vi++] = (block0 >>> 8) & 1L;
-        values[vi++] = (block0 >>> 7) & 1L;
-        values[vi++] = (block0 >>> 6) & 1L;
-        values[vi++] = (block0 >>> 5) & 1L;
-        values[vi++] = (block0 >>> 4) & 1L;
-        values[vi++] = (block0 >>> 3) & 1L;
-        values[vi++] = (block0 >>> 2) & 1L;
-        values[vi++] = (block0 >>> 1) & 1L;
-        values[vi++] = block0 & 1L;
-      }
-    }
-
-    public void set(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
+    public void decode(LongBuffer blocks, IntBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put((int) (block0 >>> 63));
+        values.put((int) ((block0 >>> 62) & 1L));
+        values.put((int) ((block0 >>> 61) & 1L));
+        values.put((int) ((block0 >>> 60) & 1L));
+        values.put((int) ((block0 >>> 59) & 1L));
+        values.put((int) ((block0 >>> 58) & 1L));
+        values.put((int) ((block0 >>> 57) & 1L));
+        values.put((int) ((block0 >>> 56) & 1L));
+        values.put((int) ((block0 >>> 55) & 1L));
+        values.put((int) ((block0 >>> 54) & 1L));
+        values.put((int) ((block0 >>> 53) & 1L));
+        values.put((int) ((block0 >>> 52) & 1L));
+        values.put((int) ((block0 >>> 51) & 1L));
+        values.put((int) ((block0 >>> 50) & 1L));
+        values.put((int) ((block0 >>> 49) & 1L));
+        values.put((int) ((block0 >>> 48) & 1L));
+        values.put((int) ((block0 >>> 47) & 1L));
+        values.put((int) ((block0 >>> 46) & 1L));
+        values.put((int) ((block0 >>> 45) & 1L));
+        values.put((int) ((block0 >>> 44) & 1L));
+        values.put((int) ((block0 >>> 43) & 1L));
+        values.put((int) ((block0 >>> 42) & 1L));
+        values.put((int) ((block0 >>> 41) & 1L));
+        values.put((int) ((block0 >>> 40) & 1L));
+        values.put((int) ((block0 >>> 39) & 1L));
+        values.put((int) ((block0 >>> 38) & 1L));
+        values.put((int) ((block0 >>> 37) & 1L));
+        values.put((int) ((block0 >>> 36) & 1L));
+        values.put((int) ((block0 >>> 35) & 1L));
+        values.put((int) ((block0 >>> 34) & 1L));
+        values.put((int) ((block0 >>> 33) & 1L));
+        values.put((int) ((block0 >>> 32) & 1L));
+        values.put((int) ((block0 >>> 31) & 1L));
+        values.put((int) ((block0 >>> 30) & 1L));
+        values.put((int) ((block0 >>> 29) & 1L));
+        values.put((int) ((block0 >>> 28) & 1L));
+        values.put((int) ((block0 >>> 27) & 1L));
+        values.put((int) ((block0 >>> 26) & 1L));
+        values.put((int) ((block0 >>> 25) & 1L));
+        values.put((int) ((block0 >>> 24) & 1L));
+        values.put((int) ((block0 >>> 23) & 1L));
+        values.put((int) ((block0 >>> 22) & 1L));
+        values.put((int) ((block0 >>> 21) & 1L));
+        values.put((int) ((block0 >>> 20) & 1L));
+        values.put((int) ((block0 >>> 19) & 1L));
+        values.put((int) ((block0 >>> 18) & 1L));
+        values.put((int) ((block0 >>> 17) & 1L));
+        values.put((int) ((block0 >>> 16) & 1L));
+        values.put((int) ((block0 >>> 15) & 1L));
+        values.put((int) ((block0 >>> 14) & 1L));
+        values.put((int) ((block0 >>> 13) & 1L));
+        values.put((int) ((block0 >>> 12) & 1L));
+        values.put((int) ((block0 >>> 11) & 1L));
+        values.put((int) ((block0 >>> 10) & 1L));
+        values.put((int) ((block0 >>> 9) & 1L));
+        values.put((int) ((block0 >>> 8) & 1L));
+        values.put((int) ((block0 >>> 7) & 1L));
+        values.put((int) ((block0 >>> 6) & 1L));
+        values.put((int) ((block0 >>> 5) & 1L));
+        values.put((int) ((block0 >>> 4) & 1L));
+        values.put((int) ((block0 >>> 3) & 1L));
+        values.put((int) ((block0 >>> 2) & 1L));
+        values.put((int) ((block0 >>> 1) & 1L));
+        values.put((int) (block0 & 1L));
+      }
+    }
+
+    public void decode(LongBuffer blocks, LongBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put(block0 >>> 63);
+        values.put((block0 >>> 62) & 1L);
+        values.put((block0 >>> 61) & 1L);
+        values.put((block0 >>> 60) & 1L);
+        values.put((block0 >>> 59) & 1L);
+        values.put((block0 >>> 58) & 1L);
+        values.put((block0 >>> 57) & 1L);
+        values.put((block0 >>> 56) & 1L);
+        values.put((block0 >>> 55) & 1L);
+        values.put((block0 >>> 54) & 1L);
+        values.put((block0 >>> 53) & 1L);
+        values.put((block0 >>> 52) & 1L);
+        values.put((block0 >>> 51) & 1L);
+        values.put((block0 >>> 50) & 1L);
+        values.put((block0 >>> 49) & 1L);
+        values.put((block0 >>> 48) & 1L);
+        values.put((block0 >>> 47) & 1L);
+        values.put((block0 >>> 46) & 1L);
+        values.put((block0 >>> 45) & 1L);
+        values.put((block0 >>> 44) & 1L);
+        values.put((block0 >>> 43) & 1L);
+        values.put((block0 >>> 42) & 1L);
+        values.put((block0 >>> 41) & 1L);
+        values.put((block0 >>> 40) & 1L);
+        values.put((block0 >>> 39) & 1L);
+        values.put((block0 >>> 38) & 1L);
+        values.put((block0 >>> 37) & 1L);
+        values.put((block0 >>> 36) & 1L);
+        values.put((block0 >>> 35) & 1L);
+        values.put((block0 >>> 34) & 1L);
+        values.put((block0 >>> 33) & 1L);
+        values.put((block0 >>> 32) & 1L);
+        values.put((block0 >>> 31) & 1L);
+        values.put((block0 >>> 30) & 1L);
+        values.put((block0 >>> 29) & 1L);
+        values.put((block0 >>> 28) & 1L);
+        values.put((block0 >>> 27) & 1L);
+        values.put((block0 >>> 26) & 1L);
+        values.put((block0 >>> 25) & 1L);
+        values.put((block0 >>> 24) & 1L);
+        values.put((block0 >>> 23) & 1L);
+        values.put((block0 >>> 22) & 1L);
+        values.put((block0 >>> 21) & 1L);
+        values.put((block0 >>> 20) & 1L);
+        values.put((block0 >>> 19) & 1L);
+        values.put((block0 >>> 18) & 1L);
+        values.put((block0 >>> 17) & 1L);
+        values.put((block0 >>> 16) & 1L);
+        values.put((block0 >>> 15) & 1L);
+        values.put((block0 >>> 14) & 1L);
+        values.put((block0 >>> 13) & 1L);
+        values.put((block0 >>> 12) & 1L);
+        values.put((block0 >>> 11) & 1L);
+        values.put((block0 >>> 10) & 1L);
+        values.put((block0 >>> 9) & 1L);
+        values.put((block0 >>> 8) & 1L);
+        values.put((block0 >>> 7) & 1L);
+        values.put((block0 >>> 6) & 1L);
+        values.put((block0 >>> 5) & 1L);
+        values.put((block0 >>> 4) & 1L);
+        values.put((block0 >>> 3) & 1L);
+        values.put((block0 >>> 2) & 1L);
+        values.put((block0 >>> 1) & 1L);
+        values.put(block0 & 1L);
+      }
+    }
+
+    public void encode(IntBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        blocks.put(((values.get() & 0xffffffffL) << 63) | ((values.get() & 0xffffffffL) << 62) | ((values.get() & 0xffffffffL) << 61) | ((values.get() & 0xffffffffL) << 60) | ((values.get() & 0xffffffffL) << 59) | ((values.get() & 0xffffffffL) << 58) | ((values.get() & 0xffffffffL) << 57) | ((values.get() & 0xffffffffL) << 56) | ((values.get() & 0xffffffffL) << 55) | ((values.get() & 0xffffffffL) << 54) | ((values.get() & 0xffffffffL) << 53) | ((values.get() & 0xffffffffL) << 52) | ((values.get() & 0xffffffffL) << 51) | ((values.get() & 0xffffffffL) << 50) | ((values.get() & 0xffffffffL) << 49) | ((values.get() & 0xffffffffL) << 48) | ((values.get() & 0xffffffffL) << 47) | ((values.get() & 0xffffffffL) << 46) | ((values.get() & 0xffffffffL) << 45) | ((values.get() & 0xffffffffL) << 44) | ((values.get() & 0xffffffffL) << 43) | ((values.get() & 0xffffffffL) << 42) | ((values.get() & 0xffffffffL) << 41) | ((values.get() & 0xffffffffL) << 40) | ((values.get() & 0xffffffffL) << 3
 9) | ((values.get() & 0xffffffffL) << 38) | ((values.get() & 0xffffffffL) << 37) | ((values.get() & 0xffffffffL) << 36) | ((values.get() & 0xffffffffL) << 35) | ((values.get() & 0xffffffffL) << 34) | ((values.get() & 0xffffffffL) << 33) | ((values.get() & 0xffffffffL) << 32) | ((values.get() & 0xffffffffL) << 31) | ((values.get() & 0xffffffffL) << 30) | ((values.get() & 0xffffffffL) << 29) | ((values.get() & 0xffffffffL) << 28) | ((values.get() & 0xffffffffL) << 27) | ((values.get() & 0xffffffffL) << 26) | ((values.get() & 0xffffffffL) << 25) | ((values.get() & 0xffffffffL) << 24) | ((values.get() & 0xffffffffL) << 23) | ((values.get() & 0xffffffffL) << 22) | ((values.get() & 0xffffffffL) << 21) | ((values.get() & 0xffffffffL) << 20) | ((values.get() & 0xffffffffL) << 19) | ((values.get() & 0xffffffffL) << 18) | ((values.get() & 0xffffffffL) << 17) | ((values.get() & 0xffffffffL) << 16) | ((values.get() & 0xffffffffL) << 15) | ((values.get() & 0xffffffffL) << 14) | ((values.
 get() & 0xffffffffL) << 13) | ((values.get() & 0xffffffffL) << 12) | ((values.get() & 0xffffffffL) << 11) | ((values.get() & 0xffffffffL) << 10) | ((values.get() & 0xffffffffL) << 9) | ((values.get() & 0xffffffffL) << 8) | ((values.get() & 0xffffffffL) << 7) | ((values.get() & 0xffffffffL) << 6) | ((values.get() & 0xffffffffL) << 5) | ((values.get() & 0xffffffffL) << 4) | ((values.get() & 0xffffffffL) << 3) | ((values.get() & 0xffffffffL) << 2) | ((values.get() & 0xffffffffL) << 1) | (values.get() & 0xffffffffL));
+      }
+    }
+
+    public void encode(LongBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
       for (int i = 0; i < iterations; ++i) {
-        blocks[bi++] = (values[vi++] << 63) | (values[vi++] << 62) | (values[vi++] << 61) | (values[vi++] << 60) | (values[vi++] << 59) | (values[vi++] << 58) | (values[vi++] << 57) | (values[vi++] << 56) | (values[vi++] << 55) | (values[vi++] << 54) | (values[vi++] << 53) | (values[vi++] << 52) | (values[vi++] << 51) | (values[vi++] << 50) | (values[vi++] << 49) | (values[vi++] << 48) | (values[vi++] << 47) | (values[vi++] << 46) | (values[vi++] << 45) | (values[vi++] << 44) | (values[vi++] << 43) | (values[vi++] << 42) | (values[vi++] << 41) | (values[vi++] << 40) | (values[vi++] << 39) | (values[vi++] << 38) | (values[vi++] << 37) | (values[vi++] << 36) | (values[vi++] << 35) | (values[vi++] << 34) | (values[vi++] << 33) | (values[vi++] << 32) | (values[vi++] << 31) | (values[vi++] << 30) | (values[vi++] << 29) | (values[vi++] << 28) | (values[vi++] << 27) | (values[vi++] << 26) | (values[vi++] << 25) | (values[vi++] << 24) | (values[vi++] << 23) | (values[vi++] << 22) | 
 (values[vi++] << 21) | (values[vi++] << 20) | (values[vi++] << 19) | (values[vi++] << 18) | (values[vi++] << 17) | (values[vi++] << 16) | (values[vi++] << 15) | (values[vi++] << 14) | (values[vi++] << 13) | (values[vi++] << 12) | (values[vi++] << 11) | (values[vi++] << 10) | (values[vi++] << 9) | (values[vi++] << 8) | (values[vi++] << 7) | (values[vi++] << 6) | (values[vi++] << 5) | (values[vi++] << 4) | (values[vi++] << 3) | (values[vi++] << 2) | (values[vi++] << 1) | values[vi++];
+        blocks.put((values.get() << 63) | (values.get() << 62) | (values.get() << 61) | (values.get() << 60) | (values.get() << 59) | (values.get() << 58) | (values.get() << 57) | (values.get() << 56) | (values.get() << 55) | (values.get() << 54) | (values.get() << 53) | (values.get() << 52) | (values.get() << 51) | (values.get() << 50) | (values.get() << 49) | (values.get() << 48) | (values.get() << 47) | (values.get() << 46) | (values.get() << 45) | (values.get() << 44) | (values.get() << 43) | (values.get() << 42) | (values.get() << 41) | (values.get() << 40) | (values.get() << 39) | (values.get() << 38) | (values.get() << 37) | (values.get() << 36) | (values.get() << 35) | (values.get() << 34) | (values.get() << 33) | (values.get() << 32) | (values.get() << 31) | (values.get() << 30) | (values.get() << 29) | (values.get() << 28) | (values.get() << 27) | (values.get() << 26) | (values.get() << 25) | (values.get() << 24) | (values.get() << 23) | (values.get() << 22) | (val
 ues.get() << 21) | (values.get() << 20) | (values.get() << 19) | (values.get() << 18) | (values.get() << 17) | (values.get() << 16) | (values.get() << 15) | (values.get() << 14) | (values.get() << 13) | (values.get() << 12) | (values.get() << 11) | (values.get() << 10) | (values.get() << 9) | (values.get() << 8) | (values.get() << 7) | (values.get() << 6) | (values.get() << 5) | (values.get() << 4) | (values.get() << 3) | (values.get() << 2) | (values.get() << 1) | values.get());
       }
     }
-  }
 
+  }
   static final class Packed64BulkOperation2 extends BulkOperation {
 
     public int blocks() {
@@ -270,55 +333,103 @@ abstract class BulkOperation {
       return 32;
     }
 
-    public void get(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
-      for (int i = 0; i < iterations; ++i) {
-        final long block0 = blocks[bi++];
-        values[vi++] = block0 >>> 62;
-        values[vi++] = (block0 >>> 60) & 3L;
-        values[vi++] = (block0 >>> 58) & 3L;
-        values[vi++] = (block0 >>> 56) & 3L;
-        values[vi++] = (block0 >>> 54) & 3L;
-        values[vi++] = (block0 >>> 52) & 3L;
-        values[vi++] = (block0 >>> 50) & 3L;
-        values[vi++] = (block0 >>> 48) & 3L;
-        values[vi++] = (block0 >>> 46) & 3L;
-        values[vi++] = (block0 >>> 44) & 3L;
-        values[vi++] = (block0 >>> 42) & 3L;
-        values[vi++] = (block0 >>> 40) & 3L;
-        values[vi++] = (block0 >>> 38) & 3L;
-        values[vi++] = (block0 >>> 36) & 3L;
-        values[vi++] = (block0 >>> 34) & 3L;
-        values[vi++] = (block0 >>> 32) & 3L;
-        values[vi++] = (block0 >>> 30) & 3L;
-        values[vi++] = (block0 >>> 28) & 3L;
-        values[vi++] = (block0 >>> 26) & 3L;
-        values[vi++] = (block0 >>> 24) & 3L;
-        values[vi++] = (block0 >>> 22) & 3L;
-        values[vi++] = (block0 >>> 20) & 3L;
-        values[vi++] = (block0 >>> 18) & 3L;
-        values[vi++] = (block0 >>> 16) & 3L;
-        values[vi++] = (block0 >>> 14) & 3L;
-        values[vi++] = (block0 >>> 12) & 3L;
-        values[vi++] = (block0 >>> 10) & 3L;
-        values[vi++] = (block0 >>> 8) & 3L;
-        values[vi++] = (block0 >>> 6) & 3L;
-        values[vi++] = (block0 >>> 4) & 3L;
-        values[vi++] = (block0 >>> 2) & 3L;
-        values[vi++] = block0 & 3L;
-      }
-    }
-
-    public void set(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
+    public void decode(LongBuffer blocks, IntBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put((int) (block0 >>> 62));
+        values.put((int) ((block0 >>> 60) & 3L));
+        values.put((int) ((block0 >>> 58) & 3L));
+        values.put((int) ((block0 >>> 56) & 3L));
+        values.put((int) ((block0 >>> 54) & 3L));
+        values.put((int) ((block0 >>> 52) & 3L));
+        values.put((int) ((block0 >>> 50) & 3L));
+        values.put((int) ((block0 >>> 48) & 3L));
+        values.put((int) ((block0 >>> 46) & 3L));
+        values.put((int) ((block0 >>> 44) & 3L));
+        values.put((int) ((block0 >>> 42) & 3L));
+        values.put((int) ((block0 >>> 40) & 3L));
+        values.put((int) ((block0 >>> 38) & 3L));
+        values.put((int) ((block0 >>> 36) & 3L));
+        values.put((int) ((block0 >>> 34) & 3L));
+        values.put((int) ((block0 >>> 32) & 3L));
+        values.put((int) ((block0 >>> 30) & 3L));
+        values.put((int) ((block0 >>> 28) & 3L));
+        values.put((int) ((block0 >>> 26) & 3L));
+        values.put((int) ((block0 >>> 24) & 3L));
+        values.put((int) ((block0 >>> 22) & 3L));
+        values.put((int) ((block0 >>> 20) & 3L));
+        values.put((int) ((block0 >>> 18) & 3L));
+        values.put((int) ((block0 >>> 16) & 3L));
+        values.put((int) ((block0 >>> 14) & 3L));
+        values.put((int) ((block0 >>> 12) & 3L));
+        values.put((int) ((block0 >>> 10) & 3L));
+        values.put((int) ((block0 >>> 8) & 3L));
+        values.put((int) ((block0 >>> 6) & 3L));
+        values.put((int) ((block0 >>> 4) & 3L));
+        values.put((int) ((block0 >>> 2) & 3L));
+        values.put((int) (block0 & 3L));
+      }
+    }
+
+    public void decode(LongBuffer blocks, LongBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put(block0 >>> 62);
+        values.put((block0 >>> 60) & 3L);
+        values.put((block0 >>> 58) & 3L);
+        values.put((block0 >>> 56) & 3L);
+        values.put((block0 >>> 54) & 3L);
+        values.put((block0 >>> 52) & 3L);
+        values.put((block0 >>> 50) & 3L);
+        values.put((block0 >>> 48) & 3L);
+        values.put((block0 >>> 46) & 3L);
+        values.put((block0 >>> 44) & 3L);
+        values.put((block0 >>> 42) & 3L);
+        values.put((block0 >>> 40) & 3L);
+        values.put((block0 >>> 38) & 3L);
+        values.put((block0 >>> 36) & 3L);
+        values.put((block0 >>> 34) & 3L);
+        values.put((block0 >>> 32) & 3L);
+        values.put((block0 >>> 30) & 3L);
+        values.put((block0 >>> 28) & 3L);
+        values.put((block0 >>> 26) & 3L);
+        values.put((block0 >>> 24) & 3L);
+        values.put((block0 >>> 22) & 3L);
+        values.put((block0 >>> 20) & 3L);
+        values.put((block0 >>> 18) & 3L);
+        values.put((block0 >>> 16) & 3L);
+        values.put((block0 >>> 14) & 3L);
+        values.put((block0 >>> 12) & 3L);
+        values.put((block0 >>> 10) & 3L);
+        values.put((block0 >>> 8) & 3L);
+        values.put((block0 >>> 6) & 3L);
+        values.put((block0 >>> 4) & 3L);
+        values.put((block0 >>> 2) & 3L);
+        values.put(block0 & 3L);
+      }
+    }
+
+    public void encode(IntBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        blocks.put(((values.get() & 0xffffffffL) << 62) | ((values.get() & 0xffffffffL) << 60) | ((values.get() & 0xffffffffL) << 58) | ((values.get() & 0xffffffffL) << 56) | ((values.get() & 0xffffffffL) << 54) | ((values.get() & 0xffffffffL) << 52) | ((values.get() & 0xffffffffL) << 50) | ((values.get() & 0xffffffffL) << 48) | ((values.get() & 0xffffffffL) << 46) | ((values.get() & 0xffffffffL) << 44) | ((values.get() & 0xffffffffL) << 42) | ((values.get() & 0xffffffffL) << 40) | ((values.get() & 0xffffffffL) << 38) | ((values.get() & 0xffffffffL) << 36) | ((values.get() & 0xffffffffL) << 34) | ((values.get() & 0xffffffffL) << 32) | ((values.get() & 0xffffffffL) << 30) | ((values.get() & 0xffffffffL) << 28) | ((values.get() & 0xffffffffL) << 26) | ((values.get() & 0xffffffffL) << 24) | ((values.get() & 0xffffffffL) << 22) | ((values.get() & 0xffffffffL) << 20) | ((values.get() & 0xffffffffL) << 18) | ((values.get() & 0xffffffffL) << 16) | ((values.get() & 0xffffffffL) << 1
 4) | ((values.get() & 0xffffffffL) << 12) | ((values.get() & 0xffffffffL) << 10) | ((values.get() & 0xffffffffL) << 8) | ((values.get() & 0xffffffffL) << 6) | ((values.get() & 0xffffffffL) << 4) | ((values.get() & 0xffffffffL) << 2) | (values.get() & 0xffffffffL));
+      }
+    }
+
+    public void encode(LongBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
       for (int i = 0; i < iterations; ++i) {
-        blocks[bi++] = (values[vi++] << 62) | (values[vi++] << 60) | (values[vi++] << 58) | (values[vi++] << 56) | (values[vi++] << 54) | (values[vi++] << 52) | (values[vi++] << 50) | (values[vi++] << 48) | (values[vi++] << 46) | (values[vi++] << 44) | (values[vi++] << 42) | (values[vi++] << 40) | (values[vi++] << 38) | (values[vi++] << 36) | (values[vi++] << 34) | (values[vi++] << 32) | (values[vi++] << 30) | (values[vi++] << 28) | (values[vi++] << 26) | (values[vi++] << 24) | (values[vi++] << 22) | (values[vi++] << 20) | (values[vi++] << 18) | (values[vi++] << 16) | (values[vi++] << 14) | (values[vi++] << 12) | (values[vi++] << 10) | (values[vi++] << 8) | (values[vi++] << 6) | (values[vi++] << 4) | (values[vi++] << 2) | values[vi++];
+        blocks.put((values.get() << 62) | (values.get() << 60) | (values.get() << 58) | (values.get() << 56) | (values.get() << 54) | (values.get() << 52) | (values.get() << 50) | (values.get() << 48) | (values.get() << 46) | (values.get() << 44) | (values.get() << 42) | (values.get() << 40) | (values.get() << 38) | (values.get() << 36) | (values.get() << 34) | (values.get() << 32) | (values.get() << 30) | (values.get() << 28) | (values.get() << 26) | (values.get() << 24) | (values.get() << 22) | (values.get() << 20) | (values.get() << 18) | (values.get() << 16) | (values.get() << 14) | (values.get() << 12) | (values.get() << 10) | (values.get() << 8) | (values.get() << 6) | (values.get() << 4) | (values.get() << 2) | values.get());
       }
     }
-  }
 
+  }
   static final class Packed64BulkOperation3 extends BulkOperation {
 
     public int blocks() {
@@ -329,91 +440,175 @@ abstract class BulkOperation {
       return 64;
     }
 
-    public void get(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
-      for (int i = 0; i < iterations; ++i) {
-        final long block0 = blocks[bi++];
-        values[vi++] = block0 >>> 61;
-        values[vi++] = (block0 >>> 58) & 7L;
-        values[vi++] = (block0 >>> 55) & 7L;
-        values[vi++] = (block0 >>> 52) & 7L;
-        values[vi++] = (block0 >>> 49) & 7L;
-        values[vi++] = (block0 >>> 46) & 7L;
-        values[vi++] = (block0 >>> 43) & 7L;
-        values[vi++] = (block0 >>> 40) & 7L;
-        values[vi++] = (block0 >>> 37) & 7L;
-        values[vi++] = (block0 >>> 34) & 7L;
-        values[vi++] = (block0 >>> 31) & 7L;
-        values[vi++] = (block0 >>> 28) & 7L;
-        values[vi++] = (block0 >>> 25) & 7L;
-        values[vi++] = (block0 >>> 22) & 7L;
-        values[vi++] = (block0 >>> 19) & 7L;
-        values[vi++] = (block0 >>> 16) & 7L;
-        values[vi++] = (block0 >>> 13) & 7L;
-        values[vi++] = (block0 >>> 10) & 7L;
-        values[vi++] = (block0 >>> 7) & 7L;
-        values[vi++] = (block0 >>> 4) & 7L;
-        values[vi++] = (block0 >>> 1) & 7L;
-        final long block1 = blocks[bi++];
-        values[vi++] = ((block0 & 1L) << 2) | (block1 >>> 62);
-        values[vi++] = (block1 >>> 59) & 7L;
-        values[vi++] = (block1 >>> 56) & 7L;
-        values[vi++] = (block1 >>> 53) & 7L;
-        values[vi++] = (block1 >>> 50) & 7L;
-        values[vi++] = (block1 >>> 47) & 7L;
-        values[vi++] = (block1 >>> 44) & 7L;
-        values[vi++] = (block1 >>> 41) & 7L;
-        values[vi++] = (block1 >>> 38) & 7L;
-        values[vi++] = (block1 >>> 35) & 7L;
-        values[vi++] = (block1 >>> 32) & 7L;
-        values[vi++] = (block1 >>> 29) & 7L;
-        values[vi++] = (block1 >>> 26) & 7L;
-        values[vi++] = (block1 >>> 23) & 7L;
-        values[vi++] = (block1 >>> 20) & 7L;
-        values[vi++] = (block1 >>> 17) & 7L;
-        values[vi++] = (block1 >>> 14) & 7L;
-        values[vi++] = (block1 >>> 11) & 7L;
-        values[vi++] = (block1 >>> 8) & 7L;
-        values[vi++] = (block1 >>> 5) & 7L;
-        values[vi++] = (block1 >>> 2) & 7L;
-        final long block2 = blocks[bi++];
-        values[vi++] = ((block1 & 3L) << 1) | (block2 >>> 63);
-        values[vi++] = (block2 >>> 60) & 7L;
-        values[vi++] = (block2 >>> 57) & 7L;
-        values[vi++] = (block2 >>> 54) & 7L;
-        values[vi++] = (block2 >>> 51) & 7L;
-        values[vi++] = (block2 >>> 48) & 7L;
-        values[vi++] = (block2 >>> 45) & 7L;
-        values[vi++] = (block2 >>> 42) & 7L;
-        values[vi++] = (block2 >>> 39) & 7L;
-        values[vi++] = (block2 >>> 36) & 7L;
-        values[vi++] = (block2 >>> 33) & 7L;
-        values[vi++] = (block2 >>> 30) & 7L;
-        values[vi++] = (block2 >>> 27) & 7L;
-        values[vi++] = (block2 >>> 24) & 7L;
-        values[vi++] = (block2 >>> 21) & 7L;
-        values[vi++] = (block2 >>> 18) & 7L;
-        values[vi++] = (block2 >>> 15) & 7L;
-        values[vi++] = (block2 >>> 12) & 7L;
-        values[vi++] = (block2 >>> 9) & 7L;
-        values[vi++] = (block2 >>> 6) & 7L;
-        values[vi++] = (block2 >>> 3) & 7L;
-        values[vi++] = block2 & 7L;
-      }
-    }
-
-    public void set(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
-      for (int i = 0; i < iterations; ++i) {
-        blocks[bi++] = (values[vi++] << 61) | (values[vi++] << 58) | (values[vi++] << 55) | (values[vi++] << 52) | (values[vi++] << 49) | (values[vi++] << 46) | (values[vi++] << 43) | (values[vi++] << 40) | (values[vi++] << 37) | (values[vi++] << 34) | (values[vi++] << 31) | (values[vi++] << 28) | (values[vi++] << 25) | (values[vi++] << 22) | (values[vi++] << 19) | (values[vi++] << 16) | (values[vi++] << 13) | (values[vi++] << 10) | (values[vi++] << 7) | (values[vi++] << 4) | (values[vi++] << 1) | (values[vi] >>> 2);
-        blocks[bi++] = (values[vi++] << 62) | (values[vi++] << 59) | (values[vi++] << 56) | (values[vi++] << 53) | (values[vi++] << 50) | (values[vi++] << 47) | (values[vi++] << 44) | (values[vi++] << 41) | (values[vi++] << 38) | (values[vi++] << 35) | (values[vi++] << 32) | (values[vi++] << 29) | (values[vi++] << 26) | (values[vi++] << 23) | (values[vi++] << 20) | (values[vi++] << 17) | (values[vi++] << 14) | (values[vi++] << 11) | (values[vi++] << 8) | (values[vi++] << 5) | (values[vi++] << 2) | (values[vi] >>> 1);
-        blocks[bi++] = (values[vi++] << 63) | (values[vi++] << 60) | (values[vi++] << 57) | (values[vi++] << 54) | (values[vi++] << 51) | (values[vi++] << 48) | (values[vi++] << 45) | (values[vi++] << 42) | (values[vi++] << 39) | (values[vi++] << 36) | (values[vi++] << 33) | (values[vi++] << 30) | (values[vi++] << 27) | (values[vi++] << 24) | (values[vi++] << 21) | (values[vi++] << 18) | (values[vi++] << 15) | (values[vi++] << 12) | (values[vi++] << 9) | (values[vi++] << 6) | (values[vi++] << 3) | values[vi++];
+    public void decode(LongBuffer blocks, IntBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put((int) (block0 >>> 61));
+        values.put((int) ((block0 >>> 58) & 7L));
+        values.put((int) ((block0 >>> 55) & 7L));
+        values.put((int) ((block0 >>> 52) & 7L));
+        values.put((int) ((block0 >>> 49) & 7L));
+        values.put((int) ((block0 >>> 46) & 7L));
+        values.put((int) ((block0 >>> 43) & 7L));
+        values.put((int) ((block0 >>> 40) & 7L));
+        values.put((int) ((block0 >>> 37) & 7L));
+        values.put((int) ((block0 >>> 34) & 7L));
+        values.put((int) ((block0 >>> 31) & 7L));
+        values.put((int) ((block0 >>> 28) & 7L));
+        values.put((int) ((block0 >>> 25) & 7L));
+        values.put((int) ((block0 >>> 22) & 7L));
+        values.put((int) ((block0 >>> 19) & 7L));
+        values.put((int) ((block0 >>> 16) & 7L));
+        values.put((int) ((block0 >>> 13) & 7L));
+        values.put((int) ((block0 >>> 10) & 7L));
+        values.put((int) ((block0 >>> 7) & 7L));
+        values.put((int) ((block0 >>> 4) & 7L));
+        values.put((int) ((block0 >>> 1) & 7L));
+        final long block1 = blocks.get();
+        values.put((int) (((block0 & 1L) << 2) | (block1 >>> 62)));
+        values.put((int) ((block1 >>> 59) & 7L));
+        values.put((int) ((block1 >>> 56) & 7L));
+        values.put((int) ((block1 >>> 53) & 7L));
+        values.put((int) ((block1 >>> 50) & 7L));
+        values.put((int) ((block1 >>> 47) & 7L));
+        values.put((int) ((block1 >>> 44) & 7L));
+        values.put((int) ((block1 >>> 41) & 7L));
+        values.put((int) ((block1 >>> 38) & 7L));
+        values.put((int) ((block1 >>> 35) & 7L));
+        values.put((int) ((block1 >>> 32) & 7L));
+        values.put((int) ((block1 >>> 29) & 7L));
+        values.put((int) ((block1 >>> 26) & 7L));
+        values.put((int) ((block1 >>> 23) & 7L));
+        values.put((int) ((block1 >>> 20) & 7L));
+        values.put((int) ((block1 >>> 17) & 7L));
+        values.put((int) ((block1 >>> 14) & 7L));
+        values.put((int) ((block1 >>> 11) & 7L));
+        values.put((int) ((block1 >>> 8) & 7L));
+        values.put((int) ((block1 >>> 5) & 7L));
+        values.put((int) ((block1 >>> 2) & 7L));
+        final long block2 = blocks.get();
+        values.put((int) (((block1 & 3L) << 1) | (block2 >>> 63)));
+        values.put((int) ((block2 >>> 60) & 7L));
+        values.put((int) ((block2 >>> 57) & 7L));
+        values.put((int) ((block2 >>> 54) & 7L));
+        values.put((int) ((block2 >>> 51) & 7L));
+        values.put((int) ((block2 >>> 48) & 7L));
+        values.put((int) ((block2 >>> 45) & 7L));
+        values.put((int) ((block2 >>> 42) & 7L));
+        values.put((int) ((block2 >>> 39) & 7L));
+        values.put((int) ((block2 >>> 36) & 7L));
+        values.put((int) ((block2 >>> 33) & 7L));
+        values.put((int) ((block2 >>> 30) & 7L));
+        values.put((int) ((block2 >>> 27) & 7L));
+        values.put((int) ((block2 >>> 24) & 7L));
+        values.put((int) ((block2 >>> 21) & 7L));
+        values.put((int) ((block2 >>> 18) & 7L));
+        values.put((int) ((block2 >>> 15) & 7L));
+        values.put((int) ((block2 >>> 12) & 7L));
+        values.put((int) ((block2 >>> 9) & 7L));
+        values.put((int) ((block2 >>> 6) & 7L));
+        values.put((int) ((block2 >>> 3) & 7L));
+        values.put((int) (block2 & 7L));
+      }
+    }
+
+    public void decode(LongBuffer blocks, LongBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put(block0 >>> 61);
+        values.put((block0 >>> 58) & 7L);
+        values.put((block0 >>> 55) & 7L);
+        values.put((block0 >>> 52) & 7L);
+        values.put((block0 >>> 49) & 7L);
+        values.put((block0 >>> 46) & 7L);
+        values.put((block0 >>> 43) & 7L);
+        values.put((block0 >>> 40) & 7L);
+        values.put((block0 >>> 37) & 7L);
+        values.put((block0 >>> 34) & 7L);
+        values.put((block0 >>> 31) & 7L);
+        values.put((block0 >>> 28) & 7L);
+        values.put((block0 >>> 25) & 7L);
+        values.put((block0 >>> 22) & 7L);
+        values.put((block0 >>> 19) & 7L);
+        values.put((block0 >>> 16) & 7L);
+        values.put((block0 >>> 13) & 7L);
+        values.put((block0 >>> 10) & 7L);
+        values.put((block0 >>> 7) & 7L);
+        values.put((block0 >>> 4) & 7L);
+        values.put((block0 >>> 1) & 7L);
+        final long block1 = blocks.get();
+        values.put(((block0 & 1L) << 2) | (block1 >>> 62));
+        values.put((block1 >>> 59) & 7L);
+        values.put((block1 >>> 56) & 7L);
+        values.put((block1 >>> 53) & 7L);
+        values.put((block1 >>> 50) & 7L);
+        values.put((block1 >>> 47) & 7L);
+        values.put((block1 >>> 44) & 7L);
+        values.put((block1 >>> 41) & 7L);
+        values.put((block1 >>> 38) & 7L);
+        values.put((block1 >>> 35) & 7L);
+        values.put((block1 >>> 32) & 7L);
+        values.put((block1 >>> 29) & 7L);
+        values.put((block1 >>> 26) & 7L);
+        values.put((block1 >>> 23) & 7L);
+        values.put((block1 >>> 20) & 7L);
+        values.put((block1 >>> 17) & 7L);
+        values.put((block1 >>> 14) & 7L);
+        values.put((block1 >>> 11) & 7L);
+        values.put((block1 >>> 8) & 7L);
+        values.put((block1 >>> 5) & 7L);
+        values.put((block1 >>> 2) & 7L);
+        final long block2 = blocks.get();
+        values.put(((block1 & 3L) << 1) | (block2 >>> 63));
+        values.put((block2 >>> 60) & 7L);
+        values.put((block2 >>> 57) & 7L);
+        values.put((block2 >>> 54) & 7L);
+        values.put((block2 >>> 51) & 7L);
+        values.put((block2 >>> 48) & 7L);
+        values.put((block2 >>> 45) & 7L);
+        values.put((block2 >>> 42) & 7L);
+        values.put((block2 >>> 39) & 7L);
+        values.put((block2 >>> 36) & 7L);
+        values.put((block2 >>> 33) & 7L);
+        values.put((block2 >>> 30) & 7L);
+        values.put((block2 >>> 27) & 7L);
+        values.put((block2 >>> 24) & 7L);
+        values.put((block2 >>> 21) & 7L);
+        values.put((block2 >>> 18) & 7L);
+        values.put((block2 >>> 15) & 7L);
+        values.put((block2 >>> 12) & 7L);
+        values.put((block2 >>> 9) & 7L);
+        values.put((block2 >>> 6) & 7L);
+        values.put((block2 >>> 3) & 7L);
+        values.put(block2 & 7L);
+      }
+    }
+
+    public void encode(IntBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        blocks.put(((values.get() & 0xffffffffL) << 61) | ((values.get() & 0xffffffffL) << 58) | ((values.get() & 0xffffffffL) << 55) | ((values.get() & 0xffffffffL) << 52) | ((values.get() & 0xffffffffL) << 49) | ((values.get() & 0xffffffffL) << 46) | ((values.get() & 0xffffffffL) << 43) | ((values.get() & 0xffffffffL) << 40) | ((values.get() & 0xffffffffL) << 37) | ((values.get() & 0xffffffffL) << 34) | ((values.get() & 0xffffffffL) << 31) | ((values.get() & 0xffffffffL) << 28) | ((values.get() & 0xffffffffL) << 25) | ((values.get() & 0xffffffffL) << 22) | ((values.get() & 0xffffffffL) << 19) | ((values.get() & 0xffffffffL) << 16) | ((values.get() & 0xffffffffL) << 13) | ((values.get() & 0xffffffffL) << 10) | ((values.get() & 0xffffffffL) << 7) | ((values.get() & 0xffffffffL) << 4) | ((values.get() & 0xffffffffL) << 1) | ((values.get(values.position()) & 0xffffffffL) >>> 2));
+        blocks.put(((values.get() & 0xffffffffL) << 62) | ((values.get() & 0xffffffffL) << 59) | ((values.get() & 0xffffffffL) << 56) | ((values.get() & 0xffffffffL) << 53) | ((values.get() & 0xffffffffL) << 50) | ((values.get() & 0xffffffffL) << 47) | ((values.get() & 0xffffffffL) << 44) | ((values.get() & 0xffffffffL) << 41) | ((values.get() & 0xffffffffL) << 38) | ((values.get() & 0xffffffffL) << 35) | ((values.get() & 0xffffffffL) << 32) | ((values.get() & 0xffffffffL) << 29) | ((values.get() & 0xffffffffL) << 26) | ((values.get() & 0xffffffffL) << 23) | ((values.get() & 0xffffffffL) << 20) | ((values.get() & 0xffffffffL) << 17) | ((values.get() & 0xffffffffL) << 14) | ((values.get() & 0xffffffffL) << 11) | ((values.get() & 0xffffffffL) << 8) | ((values.get() & 0xffffffffL) << 5) | ((values.get() & 0xffffffffL) << 2) | ((values.get(values.position()) & 0xffffffffL) >>> 1));
+        blocks.put(((values.get() & 0xffffffffL) << 63) | ((values.get() & 0xffffffffL) << 60) | ((values.get() & 0xffffffffL) << 57) | ((values.get() & 0xffffffffL) << 54) | ((values.get() & 0xffffffffL) << 51) | ((values.get() & 0xffffffffL) << 48) | ((values.get() & 0xffffffffL) << 45) | ((values.get() & 0xffffffffL) << 42) | ((values.get() & 0xffffffffL) << 39) | ((values.get() & 0xffffffffL) << 36) | ((values.get() & 0xffffffffL) << 33) | ((values.get() & 0xffffffffL) << 30) | ((values.get() & 0xffffffffL) << 27) | ((values.get() & 0xffffffffL) << 24) | ((values.get() & 0xffffffffL) << 21) | ((values.get() & 0xffffffffL) << 18) | ((values.get() & 0xffffffffL) << 15) | ((values.get() & 0xffffffffL) << 12) | ((values.get() & 0xffffffffL) << 9) | ((values.get() & 0xffffffffL) << 6) | ((values.get() & 0xffffffffL) << 3) | (values.get() & 0xffffffffL));
+      }
+    }
+
+    public void encode(LongBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        blocks.put((values.get() << 61) | (values.get() << 58) | (values.get() << 55) | (values.get() << 52) | (values.get() << 49) | (values.get() << 46) | (values.get() << 43) | (values.get() << 40) | (values.get() << 37) | (values.get() << 34) | (values.get() << 31) | (values.get() << 28) | (values.get() << 25) | (values.get() << 22) | (values.get() << 19) | (values.get() << 16) | (values.get() << 13) | (values.get() << 10) | (values.get() << 7) | (values.get() << 4) | (values.get() << 1) | (values.get(values.position()) >>> 2));
+        blocks.put((values.get() << 62) | (values.get() << 59) | (values.get() << 56) | (values.get() << 53) | (values.get() << 50) | (values.get() << 47) | (values.get() << 44) | (values.get() << 41) | (values.get() << 38) | (values.get() << 35) | (values.get() << 32) | (values.get() << 29) | (values.get() << 26) | (values.get() << 23) | (values.get() << 20) | (values.get() << 17) | (values.get() << 14) | (values.get() << 11) | (values.get() << 8) | (values.get() << 5) | (values.get() << 2) | (values.get(values.position()) >>> 1));
+        blocks.put((values.get() << 63) | (values.get() << 60) | (values.get() << 57) | (values.get() << 54) | (values.get() << 51) | (values.get() << 48) | (values.get() << 45) | (values.get() << 42) | (values.get() << 39) | (values.get() << 36) | (values.get() << 33) | (values.get() << 30) | (values.get() << 27) | (values.get() << 24) | (values.get() << 21) | (values.get() << 18) | (values.get() << 15) | (values.get() << 12) | (values.get() << 9) | (values.get() << 6) | (values.get() << 3) | values.get());
       }
     }
-  }
 
+  }
   static final class Packed64BulkOperation4 extends BulkOperation {
 
     public int blocks() {
@@ -424,39 +619,71 @@ abstract class BulkOperation {
       return 16;
     }
 
-    public void get(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
-      for (int i = 0; i < iterations; ++i) {
-        final long block0 = blocks[bi++];
-        values[vi++] = block0 >>> 60;
-        values[vi++] = (block0 >>> 56) & 15L;
-        values[vi++] = (block0 >>> 52) & 15L;
-        values[vi++] = (block0 >>> 48) & 15L;
-        values[vi++] = (block0 >>> 44) & 15L;
-        values[vi++] = (block0 >>> 40) & 15L;
-        values[vi++] = (block0 >>> 36) & 15L;
-        values[vi++] = (block0 >>> 32) & 15L;
-        values[vi++] = (block0 >>> 28) & 15L;
-        values[vi++] = (block0 >>> 24) & 15L;
-        values[vi++] = (block0 >>> 20) & 15L;
-        values[vi++] = (block0 >>> 16) & 15L;
-        values[vi++] = (block0 >>> 12) & 15L;
-        values[vi++] = (block0 >>> 8) & 15L;
-        values[vi++] = (block0 >>> 4) & 15L;
-        values[vi++] = block0 & 15L;
+    public void decode(LongBuffer blocks, IntBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put((int) (block0 >>> 60));
+        values.put((int) ((block0 >>> 56) & 15L));
+        values.put((int) ((block0 >>> 52) & 15L));
+        values.put((int) ((block0 >>> 48) & 15L));
+        values.put((int) ((block0 >>> 44) & 15L));
+        values.put((int) ((block0 >>> 40) & 15L));
+        values.put((int) ((block0 >>> 36) & 15L));
+        values.put((int) ((block0 >>> 32) & 15L));
+        values.put((int) ((block0 >>> 28) & 15L));
+        values.put((int) ((block0 >>> 24) & 15L));
+        values.put((int) ((block0 >>> 20) & 15L));
+        values.put((int) ((block0 >>> 16) & 15L));
+        values.put((int) ((block0 >>> 12) & 15L));
+        values.put((int) ((block0 >>> 8) & 15L));
+        values.put((int) ((block0 >>> 4) & 15L));
+        values.put((int) (block0 & 15L));
+      }
+    }
+
+    public void decode(LongBuffer blocks, LongBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put(block0 >>> 60);
+        values.put((block0 >>> 56) & 15L);
+        values.put((block0 >>> 52) & 15L);
+        values.put((block0 >>> 48) & 15L);
+        values.put((block0 >>> 44) & 15L);
+        values.put((block0 >>> 40) & 15L);
+        values.put((block0 >>> 36) & 15L);
+        values.put((block0 >>> 32) & 15L);
+        values.put((block0 >>> 28) & 15L);
+        values.put((block0 >>> 24) & 15L);
+        values.put((block0 >>> 20) & 15L);
+        values.put((block0 >>> 16) & 15L);
+        values.put((block0 >>> 12) & 15L);
+        values.put((block0 >>> 8) & 15L);
+        values.put((block0 >>> 4) & 15L);
+        values.put(block0 & 15L);
+      }
+    }
+
+    public void encode(IntBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        blocks.put(((values.get() & 0xffffffffL) << 60) | ((values.get() & 0xffffffffL) << 56) | ((values.get() & 0xffffffffL) << 52) | ((values.get() & 0xffffffffL) << 48) | ((values.get() & 0xffffffffL) << 44) | ((values.get() & 0xffffffffL) << 40) | ((values.get() & 0xffffffffL) << 36) | ((values.get() & 0xffffffffL) << 32) | ((values.get() & 0xffffffffL) << 28) | ((values.get() & 0xffffffffL) << 24) | ((values.get() & 0xffffffffL) << 20) | ((values.get() & 0xffffffffL) << 16) | ((values.get() & 0xffffffffL) << 12) | ((values.get() & 0xffffffffL) << 8) | ((values.get() & 0xffffffffL) << 4) | (values.get() & 0xffffffffL));
       }
     }
 
-    public void set(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
+    public void encode(LongBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
       for (int i = 0; i < iterations; ++i) {
-        blocks[bi++] = (values[vi++] << 60) | (values[vi++] << 56) | (values[vi++] << 52) | (values[vi++] << 48) | (values[vi++] << 44) | (values[vi++] << 40) | (values[vi++] << 36) | (values[vi++] << 32) | (values[vi++] << 28) | (values[vi++] << 24) | (values[vi++] << 20) | (values[vi++] << 16) | (values[vi++] << 12) | (values[vi++] << 8) | (values[vi++] << 4) | values[vi++];
+        blocks.put((values.get() << 60) | (values.get() << 56) | (values.get() << 52) | (values.get() << 48) | (values.get() << 44) | (values.get() << 40) | (values.get() << 36) | (values.get() << 32) | (values.get() << 28) | (values.get() << 24) | (values.get() << 20) | (values.get() << 16) | (values.get() << 12) | (values.get() << 8) | (values.get() << 4) | values.get());
       }
     }
-  }
 
+  }
   static final class Packed64BulkOperation5 extends BulkOperation {
 
     public int blocks() {
@@ -467,95 +694,183 @@ abstract class BulkOperation {
       return 64;
     }
 
-    public void get(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
-      for (int i = 0; i < iterations; ++i) {
-        final long block0 = blocks[bi++];
-        values[vi++] = block0 >>> 59;
-        values[vi++] = (block0 >>> 54) & 31L;
-        values[vi++] = (block0 >>> 49) & 31L;
-        values[vi++] = (block0 >>> 44) & 31L;
-        values[vi++] = (block0 >>> 39) & 31L;
-        values[vi++] = (block0 >>> 34) & 31L;
-        values[vi++] = (block0 >>> 29) & 31L;
-        values[vi++] = (block0 >>> 24) & 31L;
-        values[vi++] = (block0 >>> 19) & 31L;
-        values[vi++] = (block0 >>> 14) & 31L;
-        values[vi++] = (block0 >>> 9) & 31L;
-        values[vi++] = (block0 >>> 4) & 31L;
-        final long block1 = blocks[bi++];
-        values[vi++] = ((block0 & 15L) << 1) | (block1 >>> 63);
-        values[vi++] = (block1 >>> 58) & 31L;
-        values[vi++] = (block1 >>> 53) & 31L;
-        values[vi++] = (block1 >>> 48) & 31L;
-        values[vi++] = (block1 >>> 43) & 31L;
-        values[vi++] = (block1 >>> 38) & 31L;
-        values[vi++] = (block1 >>> 33) & 31L;
-        values[vi++] = (block1 >>> 28) & 31L;
-        values[vi++] = (block1 >>> 23) & 31L;
-        values[vi++] = (block1 >>> 18) & 31L;
-        values[vi++] = (block1 >>> 13) & 31L;
-        values[vi++] = (block1 >>> 8) & 31L;
-        values[vi++] = (block1 >>> 3) & 31L;
-        final long block2 = blocks[bi++];
-        values[vi++] = ((block1 & 7L) << 2) | (block2 >>> 62);
-        values[vi++] = (block2 >>> 57) & 31L;
-        values[vi++] = (block2 >>> 52) & 31L;
-        values[vi++] = (block2 >>> 47) & 31L;
-        values[vi++] = (block2 >>> 42) & 31L;
-        values[vi++] = (block2 >>> 37) & 31L;
-        values[vi++] = (block2 >>> 32) & 31L;
-        values[vi++] = (block2 >>> 27) & 31L;
-        values[vi++] = (block2 >>> 22) & 31L;
-        values[vi++] = (block2 >>> 17) & 31L;
-        values[vi++] = (block2 >>> 12) & 31L;
-        values[vi++] = (block2 >>> 7) & 31L;
-        values[vi++] = (block2 >>> 2) & 31L;
-        final long block3 = blocks[bi++];
-        values[vi++] = ((block2 & 3L) << 3) | (block3 >>> 61);
-        values[vi++] = (block3 >>> 56) & 31L;
-        values[vi++] = (block3 >>> 51) & 31L;
-        values[vi++] = (block3 >>> 46) & 31L;
-        values[vi++] = (block3 >>> 41) & 31L;
-        values[vi++] = (block3 >>> 36) & 31L;
-        values[vi++] = (block3 >>> 31) & 31L;
-        values[vi++] = (block3 >>> 26) & 31L;
-        values[vi++] = (block3 >>> 21) & 31L;
-        values[vi++] = (block3 >>> 16) & 31L;
-        values[vi++] = (block3 >>> 11) & 31L;
-        values[vi++] = (block3 >>> 6) & 31L;
-        values[vi++] = (block3 >>> 1) & 31L;
-        final long block4 = blocks[bi++];
-        values[vi++] = ((block3 & 1L) << 4) | (block4 >>> 60);
-        values[vi++] = (block4 >>> 55) & 31L;
-        values[vi++] = (block4 >>> 50) & 31L;
-        values[vi++] = (block4 >>> 45) & 31L;
-        values[vi++] = (block4 >>> 40) & 31L;
-        values[vi++] = (block4 >>> 35) & 31L;
-        values[vi++] = (block4 >>> 30) & 31L;
-        values[vi++] = (block4 >>> 25) & 31L;
-        values[vi++] = (block4 >>> 20) & 31L;
-        values[vi++] = (block4 >>> 15) & 31L;
-        values[vi++] = (block4 >>> 10) & 31L;
-        values[vi++] = (block4 >>> 5) & 31L;
-        values[vi++] = block4 & 31L;
-      }
-    }
-
-    public void set(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
-      for (int i = 0; i < iterations; ++i) {
-        blocks[bi++] = (values[vi++] << 59) | (values[vi++] << 54) | (values[vi++] << 49) | (values[vi++] << 44) | (values[vi++] << 39) | (values[vi++] << 34) | (values[vi++] << 29) | (values[vi++] << 24) | (values[vi++] << 19) | (values[vi++] << 14) | (values[vi++] << 9) | (values[vi++] << 4) | (values[vi] >>> 1);
-        blocks[bi++] = (values[vi++] << 63) | (values[vi++] << 58) | (values[vi++] << 53) | (values[vi++] << 48) | (values[vi++] << 43) | (values[vi++] << 38) | (values[vi++] << 33) | (values[vi++] << 28) | (values[vi++] << 23) | (values[vi++] << 18) | (values[vi++] << 13) | (values[vi++] << 8) | (values[vi++] << 3) | (values[vi] >>> 2);
-        blocks[bi++] = (values[vi++] << 62) | (values[vi++] << 57) | (values[vi++] << 52) | (values[vi++] << 47) | (values[vi++] << 42) | (values[vi++] << 37) | (values[vi++] << 32) | (values[vi++] << 27) | (values[vi++] << 22) | (values[vi++] << 17) | (values[vi++] << 12) | (values[vi++] << 7) | (values[vi++] << 2) | (values[vi] >>> 3);
-        blocks[bi++] = (values[vi++] << 61) | (values[vi++] << 56) | (values[vi++] << 51) | (values[vi++] << 46) | (values[vi++] << 41) | (values[vi++] << 36) | (values[vi++] << 31) | (values[vi++] << 26) | (values[vi++] << 21) | (values[vi++] << 16) | (values[vi++] << 11) | (values[vi++] << 6) | (values[vi++] << 1) | (values[vi] >>> 4);
-        blocks[bi++] = (values[vi++] << 60) | (values[vi++] << 55) | (values[vi++] << 50) | (values[vi++] << 45) | (values[vi++] << 40) | (values[vi++] << 35) | (values[vi++] << 30) | (values[vi++] << 25) | (values[vi++] << 20) | (values[vi++] << 15) | (values[vi++] << 10) | (values[vi++] << 5) | values[vi++];
+    public void decode(LongBuffer blocks, IntBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put((int) (block0 >>> 59));
+        values.put((int) ((block0 >>> 54) & 31L));
+        values.put((int) ((block0 >>> 49) & 31L));
+        values.put((int) ((block0 >>> 44) & 31L));
+        values.put((int) ((block0 >>> 39) & 31L));
+        values.put((int) ((block0 >>> 34) & 31L));
+        values.put((int) ((block0 >>> 29) & 31L));
+        values.put((int) ((block0 >>> 24) & 31L));
+        values.put((int) ((block0 >>> 19) & 31L));
+        values.put((int) ((block0 >>> 14) & 31L));
+        values.put((int) ((block0 >>> 9) & 31L));
+        values.put((int) ((block0 >>> 4) & 31L));
+        final long block1 = blocks.get();
+        values.put((int) (((block0 & 15L) << 1) | (block1 >>> 63)));
+        values.put((int) ((block1 >>> 58) & 31L));
+        values.put((int) ((block1 >>> 53) & 31L));
+        values.put((int) ((block1 >>> 48) & 31L));
+        values.put((int) ((block1 >>> 43) & 31L));
+        values.put((int) ((block1 >>> 38) & 31L));
+        values.put((int) ((block1 >>> 33) & 31L));
+        values.put((int) ((block1 >>> 28) & 31L));
+        values.put((int) ((block1 >>> 23) & 31L));
+        values.put((int) ((block1 >>> 18) & 31L));
+        values.put((int) ((block1 >>> 13) & 31L));
+        values.put((int) ((block1 >>> 8) & 31L));
+        values.put((int) ((block1 >>> 3) & 31L));
+        final long block2 = blocks.get();
+        values.put((int) (((block1 & 7L) << 2) | (block2 >>> 62)));
+        values.put((int) ((block2 >>> 57) & 31L));
+        values.put((int) ((block2 >>> 52) & 31L));
+        values.put((int) ((block2 >>> 47) & 31L));
+        values.put((int) ((block2 >>> 42) & 31L));
+        values.put((int) ((block2 >>> 37) & 31L));
+        values.put((int) ((block2 >>> 32) & 31L));
+        values.put((int) ((block2 >>> 27) & 31L));
+        values.put((int) ((block2 >>> 22) & 31L));
+        values.put((int) ((block2 >>> 17) & 31L));
+        values.put((int) ((block2 >>> 12) & 31L));
+        values.put((int) ((block2 >>> 7) & 31L));
+        values.put((int) ((block2 >>> 2) & 31L));
+        final long block3 = blocks.get();
+        values.put((int) (((block2 & 3L) << 3) | (block3 >>> 61)));
+        values.put((int) ((block3 >>> 56) & 31L));
+        values.put((int) ((block3 >>> 51) & 31L));
+        values.put((int) ((block3 >>> 46) & 31L));
+        values.put((int) ((block3 >>> 41) & 31L));
+        values.put((int) ((block3 >>> 36) & 31L));
+        values.put((int) ((block3 >>> 31) & 31L));
+        values.put((int) ((block3 >>> 26) & 31L));
+        values.put((int) ((block3 >>> 21) & 31L));
+        values.put((int) ((block3 >>> 16) & 31L));
+        values.put((int) ((block3 >>> 11) & 31L));
+        values.put((int) ((block3 >>> 6) & 31L));
+        values.put((int) ((block3 >>> 1) & 31L));
+        final long block4 = blocks.get();
+        values.put((int) (((block3 & 1L) << 4) | (block4 >>> 60)));
+        values.put((int) ((block4 >>> 55) & 31L));
+        values.put((int) ((block4 >>> 50) & 31L));
+        values.put((int) ((block4 >>> 45) & 31L));
+        values.put((int) ((block4 >>> 40) & 31L));
+        values.put((int) ((block4 >>> 35) & 31L));
+        values.put((int) ((block4 >>> 30) & 31L));
+        values.put((int) ((block4 >>> 25) & 31L));
+        values.put((int) ((block4 >>> 20) & 31L));
+        values.put((int) ((block4 >>> 15) & 31L));
+        values.put((int) ((block4 >>> 10) & 31L));
+        values.put((int) ((block4 >>> 5) & 31L));
+        values.put((int) (block4 & 31L));
+      }
+    }
+
+    public void decode(LongBuffer blocks, LongBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put(block0 >>> 59);
+        values.put((block0 >>> 54) & 31L);
+        values.put((block0 >>> 49) & 31L);
+        values.put((block0 >>> 44) & 31L);
+        values.put((block0 >>> 39) & 31L);
+        values.put((block0 >>> 34) & 31L);
+        values.put((block0 >>> 29) & 31L);
+        values.put((block0 >>> 24) & 31L);
+        values.put((block0 >>> 19) & 31L);
+        values.put((block0 >>> 14) & 31L);
+        values.put((block0 >>> 9) & 31L);
+        values.put((block0 >>> 4) & 31L);
+        final long block1 = blocks.get();
+        values.put(((block0 & 15L) << 1) | (block1 >>> 63));
+        values.put((block1 >>> 58) & 31L);
+        values.put((block1 >>> 53) & 31L);
+        values.put((block1 >>> 48) & 31L);
+        values.put((block1 >>> 43) & 31L);
+        values.put((block1 >>> 38) & 31L);
+        values.put((block1 >>> 33) & 31L);
+        values.put((block1 >>> 28) & 31L);
+        values.put((block1 >>> 23) & 31L);
+        values.put((block1 >>> 18) & 31L);
+        values.put((block1 >>> 13) & 31L);
+        values.put((block1 >>> 8) & 31L);
+        values.put((block1 >>> 3) & 31L);
+        final long block2 = blocks.get();
+        values.put(((block1 & 7L) << 2) | (block2 >>> 62));
+        values.put((block2 >>> 57) & 31L);
+        values.put((block2 >>> 52) & 31L);
+        values.put((block2 >>> 47) & 31L);
+        values.put((block2 >>> 42) & 31L);
+        values.put((block2 >>> 37) & 31L);
+        values.put((block2 >>> 32) & 31L);
+        values.put((block2 >>> 27) & 31L);
+        values.put((block2 >>> 22) & 31L);
+        values.put((block2 >>> 17) & 31L);
+        values.put((block2 >>> 12) & 31L);
+        values.put((block2 >>> 7) & 31L);
+        values.put((block2 >>> 2) & 31L);
+        final long block3 = blocks.get();
+        values.put(((block2 & 3L) << 3) | (block3 >>> 61));
+        values.put((block3 >>> 56) & 31L);
+        values.put((block3 >>> 51) & 31L);
+        values.put((block3 >>> 46) & 31L);
+        values.put((block3 >>> 41) & 31L);
+        values.put((block3 >>> 36) & 31L);
+        values.put((block3 >>> 31) & 31L);
+        values.put((block3 >>> 26) & 31L);
+        values.put((block3 >>> 21) & 31L);
+        values.put((block3 >>> 16) & 31L);
+        values.put((block3 >>> 11) & 31L);
+        values.put((block3 >>> 6) & 31L);
+        values.put((block3 >>> 1) & 31L);
+        final long block4 = blocks.get();
+        values.put(((block3 & 1L) << 4) | (block4 >>> 60));
+        values.put((block4 >>> 55) & 31L);
+        values.put((block4 >>> 50) & 31L);
+        values.put((block4 >>> 45) & 31L);
+        values.put((block4 >>> 40) & 31L);
+        values.put((block4 >>> 35) & 31L);
+        values.put((block4 >>> 30) & 31L);
+        values.put((block4 >>> 25) & 31L);
+        values.put((block4 >>> 20) & 31L);
+        values.put((block4 >>> 15) & 31L);
+        values.put((block4 >>> 10) & 31L);
+        values.put((block4 >>> 5) & 31L);
+        values.put(block4 & 31L);
+      }
+    }
+
+    public void encode(IntBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        blocks.put(((values.get() & 0xffffffffL) << 59) | ((values.get() & 0xffffffffL) << 54) | ((values.get() & 0xffffffffL) << 49) | ((values.get() & 0xffffffffL) << 44) | ((values.get() & 0xffffffffL) << 39) | ((values.get() & 0xffffffffL) << 34) | ((values.get() & 0xffffffffL) << 29) | ((values.get() & 0xffffffffL) << 24) | ((values.get() & 0xffffffffL) << 19) | ((values.get() & 0xffffffffL) << 14) | ((values.get() & 0xffffffffL) << 9) | ((values.get() & 0xffffffffL) << 4) | ((values.get(values.position()) & 0xffffffffL) >>> 1));
+        blocks.put(((values.get() & 0xffffffffL) << 63) | ((values.get() & 0xffffffffL) << 58) | ((values.get() & 0xffffffffL) << 53) | ((values.get() & 0xffffffffL) << 48) | ((values.get() & 0xffffffffL) << 43) | ((values.get() & 0xffffffffL) << 38) | ((values.get() & 0xffffffffL) << 33) | ((values.get() & 0xffffffffL) << 28) | ((values.get() & 0xffffffffL) << 23) | ((values.get() & 0xffffffffL) << 18) | ((values.get() & 0xffffffffL) << 13) | ((values.get() & 0xffffffffL) << 8) | ((values.get() & 0xffffffffL) << 3) | ((values.get(values.position()) & 0xffffffffL) >>> 2));
+        blocks.put(((values.get() & 0xffffffffL) << 62) | ((values.get() & 0xffffffffL) << 57) | ((values.get() & 0xffffffffL) << 52) | ((values.get() & 0xffffffffL) << 47) | ((values.get() & 0xffffffffL) << 42) | ((values.get() & 0xffffffffL) << 37) | ((values.get() & 0xffffffffL) << 32) | ((values.get() & 0xffffffffL) << 27) | ((values.get() & 0xffffffffL) << 22) | ((values.get() & 0xffffffffL) << 17) | ((values.get() & 0xffffffffL) << 12) | ((values.get() & 0xffffffffL) << 7) | ((values.get() & 0xffffffffL) << 2) | ((values.get(values.position()) & 0xffffffffL) >>> 3));
+        blocks.put(((values.get() & 0xffffffffL) << 61) | ((values.get() & 0xffffffffL) << 56) | ((values.get() & 0xffffffffL) << 51) | ((values.get() & 0xffffffffL) << 46) | ((values.get() & 0xffffffffL) << 41) | ((values.get() & 0xffffffffL) << 36) | ((values.get() & 0xffffffffL) << 31) | ((values.get() & 0xffffffffL) << 26) | ((values.get() & 0xffffffffL) << 21) | ((values.get() & 0xffffffffL) << 16) | ((values.get() & 0xffffffffL) << 11) | ((values.get() & 0xffffffffL) << 6) | ((values.get() & 0xffffffffL) << 1) | ((values.get(values.position()) & 0xffffffffL) >>> 4));
+        blocks.put(((values.get() & 0xffffffffL) << 60) | ((values.get() & 0xffffffffL) << 55) | ((values.get() & 0xffffffffL) << 50) | ((values.get() & 0xffffffffL) << 45) | ((values.get() & 0xffffffffL) << 40) | ((values.get() & 0xffffffffL) << 35) | ((values.get() & 0xffffffffL) << 30) | ((values.get() & 0xffffffffL) << 25) | ((values.get() & 0xffffffffL) << 20) | ((values.get() & 0xffffffffL) << 15) | ((values.get() & 0xffffffffL) << 10) | ((values.get() & 0xffffffffL) << 5) | (values.get() & 0xffffffffL));
+      }
+    }
+
+    public void encode(LongBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        blocks.put((values.get() << 59) | (values.get() << 54) | (values.get() << 49) | (values.get() << 44) | (values.get() << 39) | (values.get() << 34) | (values.get() << 29) | (values.get() << 24) | (values.get() << 19) | (values.get() << 14) | (values.get() << 9) | (values.get() << 4) | (values.get(values.position()) >>> 1));
+        blocks.put((values.get() << 63) | (values.get() << 58) | (values.get() << 53) | (values.get() << 48) | (values.get() << 43) | (values.get() << 38) | (values.get() << 33) | (values.get() << 28) | (values.get() << 23) | (values.get() << 18) | (values.get() << 13) | (values.get() << 8) | (values.get() << 3) | (values.get(values.position()) >>> 2));
+        blocks.put((values.get() << 62) | (values.get() << 57) | (values.get() << 52) | (values.get() << 47) | (values.get() << 42) | (values.get() << 37) | (values.get() << 32) | (values.get() << 27) | (values.get() << 22) | (values.get() << 17) | (values.get() << 12) | (values.get() << 7) | (values.get() << 2) | (values.get(values.position()) >>> 3));
+        blocks.put((values.get() << 61) | (values.get() << 56) | (values.get() << 51) | (values.get() << 46) | (values.get() << 41) | (values.get() << 36) | (values.get() << 31) | (values.get() << 26) | (values.get() << 21) | (values.get() << 16) | (values.get() << 11) | (values.get() << 6) | (values.get() << 1) | (values.get(values.position()) >>> 4));
+        blocks.put((values.get() << 60) | (values.get() << 55) | (values.get() << 50) | (values.get() << 45) | (values.get() << 40) | (values.get() << 35) | (values.get() << 30) | (values.get() << 25) | (values.get() << 20) | (values.get() << 15) | (values.get() << 10) | (values.get() << 5) | values.get());
       }
     }
-  }
 
+  }
   static final class Packed64BulkOperation6 extends BulkOperation {
 
     public int blocks() {
@@ -566,59 +881,111 @@ abstract class BulkOperation {
       return 32;
     }
 
-    public void get(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
-      for (int i = 0; i < iterations; ++i) {
-        final long block0 = blocks[bi++];
-        values[vi++] = block0 >>> 58;
-        values[vi++] = (block0 >>> 52) & 63L;
-        values[vi++] = (block0 >>> 46) & 63L;
-        values[vi++] = (block0 >>> 40) & 63L;
-        values[vi++] = (block0 >>> 34) & 63L;
-        values[vi++] = (block0 >>> 28) & 63L;
-        values[vi++] = (block0 >>> 22) & 63L;
-        values[vi++] = (block0 >>> 16) & 63L;
-        values[vi++] = (block0 >>> 10) & 63L;
-        values[vi++] = (block0 >>> 4) & 63L;
-        final long block1 = blocks[bi++];
-        values[vi++] = ((block0 & 15L) << 2) | (block1 >>> 62);
-        values[vi++] = (block1 >>> 56) & 63L;
-        values[vi++] = (block1 >>> 50) & 63L;
-        values[vi++] = (block1 >>> 44) & 63L;
-        values[vi++] = (block1 >>> 38) & 63L;
-        values[vi++] = (block1 >>> 32) & 63L;
-        values[vi++] = (block1 >>> 26) & 63L;
-        values[vi++] = (block1 >>> 20) & 63L;
-        values[vi++] = (block1 >>> 14) & 63L;
-        values[vi++] = (block1 >>> 8) & 63L;
-        values[vi++] = (block1 >>> 2) & 63L;
-        final long block2 = blocks[bi++];
-        values[vi++] = ((block1 & 3L) << 4) | (block2 >>> 60);
-        values[vi++] = (block2 >>> 54) & 63L;
-        values[vi++] = (block2 >>> 48) & 63L;
-        values[vi++] = (block2 >>> 42) & 63L;
-        values[vi++] = (block2 >>> 36) & 63L;
-        values[vi++] = (block2 >>> 30) & 63L;
-        values[vi++] = (block2 >>> 24) & 63L;
-        values[vi++] = (block2 >>> 18) & 63L;
-        values[vi++] = (block2 >>> 12) & 63L;
-        values[vi++] = (block2 >>> 6) & 63L;
-        values[vi++] = block2 & 63L;
+    public void decode(LongBuffer blocks, IntBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put((int) (block0 >>> 58));
+        values.put((int) ((block0 >>> 52) & 63L));
+        values.put((int) ((block0 >>> 46) & 63L));
+        values.put((int) ((block0 >>> 40) & 63L));
+        values.put((int) ((block0 >>> 34) & 63L));
+        values.put((int) ((block0 >>> 28) & 63L));
+        values.put((int) ((block0 >>> 22) & 63L));
+        values.put((int) ((block0 >>> 16) & 63L));
+        values.put((int) ((block0 >>> 10) & 63L));
+        values.put((int) ((block0 >>> 4) & 63L));
+        final long block1 = blocks.get();
+        values.put((int) (((block0 & 15L) << 2) | (block1 >>> 62)));
+        values.put((int) ((block1 >>> 56) & 63L));
+        values.put((int) ((block1 >>> 50) & 63L));
+        values.put((int) ((block1 >>> 44) & 63L));
+        values.put((int) ((block1 >>> 38) & 63L));
+        values.put((int) ((block1 >>> 32) & 63L));
+        values.put((int) ((block1 >>> 26) & 63L));
+        values.put((int) ((block1 >>> 20) & 63L));
+        values.put((int) ((block1 >>> 14) & 63L));
+        values.put((int) ((block1 >>> 8) & 63L));
+        values.put((int) ((block1 >>> 2) & 63L));
+        final long block2 = blocks.get();
+        values.put((int) (((block1 & 3L) << 4) | (block2 >>> 60)));
+        values.put((int) ((block2 >>> 54) & 63L));
+        values.put((int) ((block2 >>> 48) & 63L));
+        values.put((int) ((block2 >>> 42) & 63L));
+        values.put((int) ((block2 >>> 36) & 63L));
+        values.put((int) ((block2 >>> 30) & 63L));
+        values.put((int) ((block2 >>> 24) & 63L));
+        values.put((int) ((block2 >>> 18) & 63L));
+        values.put((int) ((block2 >>> 12) & 63L));
+        values.put((int) ((block2 >>> 6) & 63L));
+        values.put((int) (block2 & 63L));
+      }
+    }
+
+    public void decode(LongBuffer blocks, LongBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put(block0 >>> 58);
+        values.put((block0 >>> 52) & 63L);
+        values.put((block0 >>> 46) & 63L);
+        values.put((block0 >>> 40) & 63L);
+        values.put((block0 >>> 34) & 63L);
+        values.put((block0 >>> 28) & 63L);
+        values.put((block0 >>> 22) & 63L);
+        values.put((block0 >>> 16) & 63L);
+        values.put((block0 >>> 10) & 63L);
+        values.put((block0 >>> 4) & 63L);
+        final long block1 = blocks.get();
+        values.put(((block0 & 15L) << 2) | (block1 >>> 62));
+        values.put((block1 >>> 56) & 63L);
+        values.put((block1 >>> 50) & 63L);
+        values.put((block1 >>> 44) & 63L);
+        values.put((block1 >>> 38) & 63L);
+        values.put((block1 >>> 32) & 63L);
+        values.put((block1 >>> 26) & 63L);
+        values.put((block1 >>> 20) & 63L);
+        values.put((block1 >>> 14) & 63L);
+        values.put((block1 >>> 8) & 63L);
+        values.put((block1 >>> 2) & 63L);
+        final long block2 = blocks.get();
+        values.put(((block1 & 3L) << 4) | (block2 >>> 60));
+        values.put((block2 >>> 54) & 63L);
+        values.put((block2 >>> 48) & 63L);
+        values.put((block2 >>> 42) & 63L);
+        values.put((block2 >>> 36) & 63L);
+        values.put((block2 >>> 30) & 63L);
+        values.put((block2 >>> 24) & 63L);
+        values.put((block2 >>> 18) & 63L);
+        values.put((block2 >>> 12) & 63L);
+        values.put((block2 >>> 6) & 63L);
+        values.put(block2 & 63L);
+      }
+    }
+
+    public void encode(IntBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        blocks.put(((values.get() & 0xffffffffL) << 58) | ((values.get() & 0xffffffffL) << 52) | ((values.get() & 0xffffffffL) << 46) | ((values.get() & 0xffffffffL) << 40) | ((values.get() & 0xffffffffL) << 34) | ((values.get() & 0xffffffffL) << 28) | ((values.get() & 0xffffffffL) << 22) | ((values.get() & 0xffffffffL) << 16) | ((values.get() & 0xffffffffL) << 10) | ((values.get() & 0xffffffffL) << 4) | ((values.get(values.position()) & 0xffffffffL) >>> 2));
+        blocks.put(((values.get() & 0xffffffffL) << 62) | ((values.get() & 0xffffffffL) << 56) | ((values.get() & 0xffffffffL) << 50) | ((values.get() & 0xffffffffL) << 44) | ((values.get() & 0xffffffffL) << 38) | ((values.get() & 0xffffffffL) << 32) | ((values.get() & 0xffffffffL) << 26) | ((values.get() & 0xffffffffL) << 20) | ((values.get() & 0xffffffffL) << 14) | ((values.get() & 0xffffffffL) << 8) | ((values.get() & 0xffffffffL) << 2) | ((values.get(values.position()) & 0xffffffffL) >>> 4));
+        blocks.put(((values.get() & 0xffffffffL) << 60) | ((values.get() & 0xffffffffL) << 54) | ((values.get() & 0xffffffffL) << 48) | ((values.get() & 0xffffffffL) << 42) | ((values.get() & 0xffffffffL) << 36) | ((values.get() & 0xffffffffL) << 30) | ((values.get() & 0xffffffffL) << 24) | ((values.get() & 0xffffffffL) << 18) | ((values.get() & 0xffffffffL) << 12) | ((values.get() & 0xffffffffL) << 6) | (values.get() & 0xffffffffL));
+      }
+    }
+
+    public void encode(LongBuffer values, LongBuffer blocks, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        blocks.put((values.get() << 58) | (values.get() << 52) | (values.get() << 46) | (values.get() << 40) | (values.get() << 34) | (values.get() << 28) | (values.get() << 22) | (values.get() << 16) | (values.get() << 10) | (values.get() << 4) | (values.get(values.position()) >>> 2));
+        blocks.put((values.get() << 62) | (values.get() << 56) | (values.get() << 50) | (values.get() << 44) | (values.get() << 38) | (values.get() << 32) | (values.get() << 26) | (values.get() << 20) | (values.get() << 14) | (values.get() << 8) | (values.get() << 2) | (values.get(values.position()) >>> 4));
+        blocks.put((values.get() << 60) | (values.get() << 54) | (values.get() << 48) | (values.get() << 42) | (values.get() << 36) | (values.get() << 30) | (values.get() << 24) | (values.get() << 18) | (values.get() << 12) | (values.get() << 6) | values.get());
       }
     }
 
-    public void set(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
-      for (int i = 0; i < iterations; ++i) {
-        blocks[bi++] = (values[vi++] << 58) | (values[vi++] << 52) | (values[vi++] << 46) | (values[vi++] << 40) | (values[vi++] << 34) | (values[vi++] << 28) | (values[vi++] << 22) | (values[vi++] << 16) | (values[vi++] << 10) | (values[vi++] << 4) | (values[vi] >>> 2);
-        blocks[bi++] = (values[vi++] << 62) | (values[vi++] << 56) | (values[vi++] << 50) | (values[vi++] << 44) | (values[vi++] << 38) | (values[vi++] << 32) | (values[vi++] << 26) | (values[vi++] << 20) | (values[vi++] << 14) | (values[vi++] << 8) | (values[vi++] << 2) | (values[vi] >>> 4);
-        blocks[bi++] = (values[vi++] << 60) | (values[vi++] << 54) | (values[vi++] << 48) | (values[vi++] << 42) | (values[vi++] << 36) | (values[vi++] << 30) | (values[vi++] << 24) | (values[vi++] << 18) | (values[vi++] << 12) | (values[vi++] << 6) | values[vi++];
-      }
-    }
   }
-
   static final class Packed64BulkOperation7 extends BulkOperation {
 
     public int blocks() {
@@ -629,99 +996,191 @@ abstract class BulkOperation {
       return 64;
     }
 
-    public void get(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
-      for (int i = 0; i < iterations; ++i) {
-        final long block0 = blocks[bi++];
-        values[vi++] = block0 >>> 57;
-        values[vi++] = (block0 >>> 50) & 127L;
-        values[vi++] = (block0 >>> 43) & 127L;
-        values[vi++] = (block0 >>> 36) & 127L;
-        values[vi++] = (block0 >>> 29) & 127L;
-        values[vi++] = (block0 >>> 22) & 127L;
-        values[vi++] = (block0 >>> 15) & 127L;
-        values[vi++] = (block0 >>> 8) & 127L;
-        values[vi++] = (block0 >>> 1) & 127L;
-        final long block1 = blocks[bi++];
-        values[vi++] = ((block0 & 1L) << 6) | (block1 >>> 58);
-        values[vi++] = (block1 >>> 51) & 127L;
-        values[vi++] = (block1 >>> 44) & 127L;
-        values[vi++] = (block1 >>> 37) & 127L;
-        values[vi++] = (block1 >>> 30) & 127L;
-        values[vi++] = (block1 >>> 23) & 127L;
-        values[vi++] = (block1 >>> 16) & 127L;
-        values[vi++] = (block1 >>> 9) & 127L;
-        values[vi++] = (block1 >>> 2) & 127L;
-        final long block2 = blocks[bi++];
-        values[vi++] = ((block1 & 3L) << 5) | (block2 >>> 59);
-        values[vi++] = (block2 >>> 52) & 127L;
-        values[vi++] = (block2 >>> 45) & 127L;
-        values[vi++] = (block2 >>> 38) & 127L;
-        values[vi++] = (block2 >>> 31) & 127L;
-        values[vi++] = (block2 >>> 24) & 127L;
-        values[vi++] = (block2 >>> 17) & 127L;
-        values[vi++] = (block2 >>> 10) & 127L;
-        values[vi++] = (block2 >>> 3) & 127L;
-        final long block3 = blocks[bi++];
-        values[vi++] = ((block2 & 7L) << 4) | (block3 >>> 60);
-        values[vi++] = (block3 >>> 53) & 127L;
-        values[vi++] = (block3 >>> 46) & 127L;
-        values[vi++] = (block3 >>> 39) & 127L;
-        values[vi++] = (block3 >>> 32) & 127L;
-        values[vi++] = (block3 >>> 25) & 127L;
-        values[vi++] = (block3 >>> 18) & 127L;
-        values[vi++] = (block3 >>> 11) & 127L;
-        values[vi++] = (block3 >>> 4) & 127L;
-        final long block4 = blocks[bi++];
-        values[vi++] = ((block3 & 15L) << 3) | (block4 >>> 61);
-        values[vi++] = (block4 >>> 54) & 127L;
-        values[vi++] = (block4 >>> 47) & 127L;
-        values[vi++] = (block4 >>> 40) & 127L;
-        values[vi++] = (block4 >>> 33) & 127L;
-        values[vi++] = (block4 >>> 26) & 127L;
-        values[vi++] = (block4 >>> 19) & 127L;
-        values[vi++] = (block4 >>> 12) & 127L;
-        values[vi++] = (block4 >>> 5) & 127L;
-        final long block5 = blocks[bi++];
-        values[vi++] = ((block4 & 31L) << 2) | (block5 >>> 62);
-        values[vi++] = (block5 >>> 55) & 127L;
-        values[vi++] = (block5 >>> 48) & 127L;
-        values[vi++] = (block5 >>> 41) & 127L;
-        values[vi++] = (block5 >>> 34) & 127L;
-        values[vi++] = (block5 >>> 27) & 127L;
-        values[vi++] = (block5 >>> 20) & 127L;
-        values[vi++] = (block5 >>> 13) & 127L;
-        values[vi++] = (block5 >>> 6) & 127L;
-        final long block6 = blocks[bi++];
-        values[vi++] = ((block5 & 63L) << 1) | (block6 >>> 63);
-        values[vi++] = (block6 >>> 56) & 127L;
-        values[vi++] = (block6 >>> 49) & 127L;
-        values[vi++] = (block6 >>> 42) & 127L;
-        values[vi++] = (block6 >>> 35) & 127L;
-        values[vi++] = (block6 >>> 28) & 127L;
-        values[vi++] = (block6 >>> 21) & 127L;
-        values[vi++] = (block6 >>> 14) & 127L;
-        values[vi++] = (block6 >>> 7) & 127L;
-        values[vi++] = block6 & 127L;
-      }
-    }
-
-    public void set(long[] blocks, int bi, long[] values, int vi, int iterations) {
-      assert bi + iterations * blocks() <= blocks.length;
-      assert vi + iterations * values() <= values.length;
-      for (int i = 0; i < iterations; ++i) {
-        blocks[bi++] = (values[vi++] << 57) | (values[vi++] << 50) | (values[vi++] << 43) | (values[vi++] << 36) | (values[vi++] << 29) | (values[vi++] << 22) | (values[vi++] << 15) | (values[vi++] << 8) | (values[vi++] << 1) | (values[vi] >>> 6);
-        blocks[bi++] = (values[vi++] << 58) | (values[vi++] << 51) | (values[vi++] << 44) | (values[vi++] << 37) | (values[vi++] << 30) | (values[vi++] << 23) | (values[vi++] << 16) | (values[vi++] << 9) | (values[vi++] << 2) | (values[vi] >>> 5);
-        blocks[bi++] = (values[vi++] << 59) | (values[vi++] << 52) | (values[vi++] << 45) | (values[vi++] << 38) | (values[vi++] << 31) | (values[vi++] << 24) | (values[vi++] << 17) | (values[vi++] << 10) | (values[vi++] << 3) | (values[vi] >>> 4);
-        blocks[bi++] = (values[vi++] << 60) | (values[vi++] << 53) | (values[vi++] << 46) | (values[vi++] << 39) | (values[vi++] << 32) | (values[vi++] << 25) | (values[vi++] << 18) | (values[vi++] << 11) | (values[vi++] << 4) | (values[vi] >>> 3);
-        blocks[bi++] = (values[vi++] << 61) | (values[vi++] << 54) | (values[vi++] << 47) | (values[vi++] << 40) | (values[vi++] << 33) | (values[vi++] << 26) | (values[vi++] << 19) | (values[vi++] << 12) | (values[vi++] << 5) | (values[vi] >>> 2);
-        blocks[bi++] = (values[vi++] << 62) | (values[vi++] << 55) | (values[vi++] << 48) | (values[vi++] << 41) | (values[vi++] << 34) | (values[vi++] << 27) | (values[vi++] << 20) | (values[vi++] << 13) | (values[vi++] << 6) | (values[vi] >>> 1);
-        blocks[bi++] = (values[vi++] << 63) | (values[vi++] << 56) | (values[vi++] << 49) | (values[vi++] << 42) | (values[vi++] << 35) | (values[vi++] << 28) | (values[vi++] << 21) | (values[vi++] << 14) | (values[vi++] << 7) | values[vi++];
+    public void decode(LongBuffer blocks, IntBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put((int) (block0 >>> 57));
+        values.put((int) ((block0 >>> 50) & 127L));
+        values.put((int) ((block0 >>> 43) & 127L));
+        values.put((int) ((block0 >>> 36) & 127L));
+        values.put((int) ((block0 >>> 29) & 127L));
+        values.put((int) ((block0 >>> 22) & 127L));
+        values.put((int) ((block0 >>> 15) & 127L));
+        values.put((int) ((block0 >>> 8) & 127L));
+        values.put((int) ((block0 >>> 1) & 127L));
+        final long block1 = blocks.get();
+        values.put((int) (((block0 & 1L) << 6) | (block1 >>> 58)));
+        values.put((int) ((block1 >>> 51) & 127L));
+        values.put((int) ((block1 >>> 44) & 127L));
+        values.put((int) ((block1 >>> 37) & 127L));
+        values.put((int) ((block1 >>> 30) & 127L));
+        values.put((int) ((block1 >>> 23) & 127L));
+        values.put((int) ((block1 >>> 16) & 127L));
+        values.put((int) ((block1 >>> 9) & 127L));
+        values.put((int) ((block1 >>> 2) & 127L));
+        final long block2 = blocks.get();
+        values.put((int) (((block1 & 3L) << 5) | (block2 >>> 59)));
+        values.put((int) ((block2 >>> 52) & 127L));
+        values.put((int) ((block2 >>> 45) & 127L));
+        values.put((int) ((block2 >>> 38) & 127L));
+        values.put((int) ((block2 >>> 31) & 127L));
+        values.put((int) ((block2 >>> 24) & 127L));
+        values.put((int) ((block2 >>> 17) & 127L));
+        values.put((int) ((block2 >>> 10) & 127L));
+        values.put((int) ((block2 >>> 3) & 127L));
+        final long block3 = blocks.get();
+        values.put((int) (((block2 & 7L) << 4) | (block3 >>> 60)));
+        values.put((int) ((block3 >>> 53) & 127L));
+        values.put((int) ((block3 >>> 46) & 127L));
+        values.put((int) ((block3 >>> 39) & 127L));
+        values.put((int) ((block3 >>> 32) & 127L));
+        values.put((int) ((block3 >>> 25) & 127L));
+        values.put((int) ((block3 >>> 18) & 127L));
+        values.put((int) ((block3 >>> 11) & 127L));
+        values.put((int) ((block3 >>> 4) & 127L));
+        final long block4 = blocks.get();
+        values.put((int) (((block3 & 15L) << 3) | (block4 >>> 61)));
+        values.put((int) ((block4 >>> 54) & 127L));
+        values.put((int) ((block4 >>> 47) & 127L));
+        values.put((int) ((block4 >>> 40) & 127L));
+        values.put((int) ((block4 >>> 33) & 127L));
+        values.put((int) ((block4 >>> 26) & 127L));
+        values.put((int) ((block4 >>> 19) & 127L));
+        values.put((int) ((block4 >>> 12) & 127L));
+        values.put((int) ((block4 >>> 5) & 127L));
+        final long block5 = blocks.get();
+        values.put((int) (((block4 & 31L) << 2) | (block5 >>> 62)));
+        values.put((int) ((block5 >>> 55) & 127L));
+        values.put((int) ((block5 >>> 48) & 127L));
+        values.put((int) ((block5 >>> 41) & 127L));
+        values.put((int) ((block5 >>> 34) & 127L));
+        values.put((int) ((block5 >>> 27) & 127L));
+        values.put((int) ((block5 >>> 20) & 127L));
+        values.put((int) ((block5 >>> 13) & 127L));
+        values.put((int) ((block5 >>> 6) & 127L));
+        final long block6 = blocks.get();
+        values.put((int) (((block5 & 63L) << 1) | (block6 >>> 63)));
+        values.put((int) ((block6 >>> 56) & 127L));
+        values.put((int) ((block6 >>> 49) & 127L));
+        values.put((int) ((block6 >>> 42) & 127L));
+        values.put((int) ((block6 >>> 35) & 127L));
+        values.put((int) ((block6 >>> 28) & 127L));
+        values.put((int) ((block6 >>> 21) & 127L));
+        values.put((int) ((block6 >>> 14) & 127L));
+        values.put((int) ((block6 >>> 7) & 127L));
+        values.put((int) (block6 & 127L));
+      }
+    }
+
+    public void decode(LongBuffer blocks, LongBuffer values, int iterations) {
+      assert blocks.position() + iterations * blocks() <= blocks.limit();
+      assert values.position() + iterations * values() <= values.limit();
+      for (int i = 0; i < iterations; ++i) {
+        final long block0 = blocks.get();
+        values.put(block0 >>> 57);
+        values.put((block0 >>> 50) & 127L);
+        values.put((block0 >>> 43) & 127L);
+        values.put((block0 >>> 36) & 127L);
+        values.put((block0 >>> 29) & 127L);
+        values.put((block0 >>> 22) & 127L);
+        values.put((block0 >>> 15) & 127L);
+        values.put((block0 >>> 8) & 127L);
+        values.put((block0 >>> 1) & 127L);
+        final long block1 = blocks.get();
+        values.put(((block0 & 1L) << 6) | (block1 >>> 58));
+        values.put((block1 >>> 51) & 127L);
+        values.put((block1 >>> 44) & 127L);
+        values.put((block1 >>> 37) & 127L);
+        values.put((block1 >>> 30) & 127L);
+        values.put((block1 >>> 23) & 127L);
+        values.put((block1 >>> 16) & 127L);
+        values.put((block1 >>> 9) & 127L);
+        values.put((block1 >>> 2) & 127L);
+        final long block2 = blocks.get();
+        values.put(((block1 & 3L) << 5) | (block2 >>> 59));
+        values.put((block2 >>> 52) & 127L);
+        values.put((block2 >>> 45) & 127L);
+        values.put((block2 >>> 38) & 127L);
+        values.put((block2 >>> 31) & 127L);
+        values.put((block2 >>> 24) & 127L);
+        values.put((block2 >>> 17) & 127L);
+        values.put((block2 >>> 10) & 127L);
+        values.put((block2 >>> 3) & 127L);

[... 16798 lines stripped ...]