public static void jenkins(final BitVector bv,final long prefixLength,final long[] aa,final long bb[],final long cc[],final long[] h){
  if (prefixLength == 0) {
    final long seed=aa[0];
    h[0]=seed ^ 0x8de6a918d6538324L;
    h[1]=seed ^ 0x6bda2aef21654e7dL;
    h[2]=seed ^ 0x36071e726d0ba0c5L;
    return;
  }
  int stateOffset=(int)(prefixLength / (3 * Long.SIZE));
  long from=(stateOffset * 3) * Long.SIZE;
  long a=aa[stateOffset];
  long b=bb[stateOffset];
  long c=cc[stateOffset];
  if (prefixLength - from > Long.SIZE * 2) {
    a+=bv.getLong(from,from + Long.SIZE);
    b+=bv.getLong(from + Long.SIZE,from + 2 * Long.SIZE);
    c+=bv.getLong(from + 2 * Long.SIZE,Math.min(from + 3 * Long.SIZE,prefixLength));
    a-=b;
    a-=c;
    a^=(c >>> 43);
    b-=c;
    b-=a;
    b^=(a << 9);
    c-=a;
    c-=b;
    c^=(b >>> 8);
    a-=b;
    a-=c;
    a^=(c >>> 38);
    b-=c;
    b-=a;
    b^=(a << 23);
    c-=a;
    c-=b;
    c^=(b >>> 5);
    a-=b;
    a-=c;
    a^=(c >>> 35);
    b-=c;
    b-=a;
    b^=(a << 49);
    c-=a;
    c-=b;
    c^=(b >>> 11);
    a-=b;
    a-=c;
    a^=(c >>> 12);
    b-=c;
    b-=a;
    b^=(a << 18);
    c-=a;
    c-=b;
    c^=(b >>> 22);
    from+=3 * Long.SIZE;
  }
  c+=prefixLength;
  long residual=prefixLength - from;
  if (residual > 0) {
    if (residual > Long.SIZE) {
      a+=bv.getLong(from,from + Long.SIZE);
      residual-=Long.SIZE;
    }
    if (residual != 0)     b+=bv.getLong(prefixLength - residual,prefixLength);
  }
  a-=b;
  a-=c;
  a^=(c >>> 43);
  b-=c;
  b-=a;
  b^=(a << 9);
  c-=a;
  c-=b;
  c^=(b >>> 8);
  a-=b;
  a-=c;
  a^=(c >>> 38);
  b-=c;
  b-=a;
  b^=(a << 23);
  c-=a;
  c-=b;
  c^=(b >>> 5);
  a-=b;
  a-=c;
  a^=(c >>> 35);
  b-=c;
  b-=a;
  b^=(a << 49);
  c-=a;
  c-=b;
  c^=(b >>> 11);
  a-=b;
  a-=c;
  a^=(c >>> 12);
  b-=c;
  b-=a;
  b^=(a << 18);
  c-=a;
  c-=b;
  c^=(b >>> 22);
  h[0]=a;
  h[1]=b;
  h[2]=c;
}

public static void jenkins ( final BitVector bv , final long prefixLength , final long [ ] aa , final long bb [ ] , final long cc [ ] , final long [ ] h ) { if ( prefixLength == 0 ) { final long seed = aa [ 0 ] ; h [ 0 ] = seed ^ 0x8de6a918d6538324L ; h [ 1 ] = seed ^ 0x6bda2aef21654e7dL ; h [ 2 ] = seed ^ 0x36071e726d0ba0c5L ; return ; } int stateOffset = ( int ) ( prefixLength / ( 3 * Long . SIZE ) ) ; long from = ( stateOffset * 3 ) * Long . SIZE ; long a = aa [ stateOffset ] ; long b = bb [ stateOffset ] ; long c = cc [ stateOffset ] ; if ( prefixLength - from > Long . SIZE * 2 ) { a += bv . getLong ( from , from + Long . SIZE ) ; b += bv . getLong ( from + Long . SIZE , from + 2 * Long . SIZE ) ; c += bv . getLong ( from + 2 * Long . SIZE , Math . min ( from + 3 * Long . SIZE , prefixLength ) ) ; a -= b ; a -= c ; a ^= ( c > > > 43 ) ; b -= c ; b -= a ; b ^= ( a << 9 ) ; c -= a ; c -= b ; c ^= ( b > > > 8 ) ; a -= b ; a -= c ; a ^= ( c > > > 38 ) ; b -= c ; b -= a ; b ^= ( a << 23 ) ; c -= a ; c -= b ; c ^= ( b > > > 5 ) ; a -= b ; a -= c ; a ^= ( c > > > 35 ) ; b -= c ; b -= a ; b ^= ( a << 49 ) ; c -= a ; c -= b ; c ^= ( b > > > 11 ) ; a -= b ; a -= c ; a ^= ( c > > > 12 ) ; b -= c ; b -= a ; b ^= ( a << 18 ) ; c -= a ; c -= b ; c ^= ( b > > > 22 ) ; from += 3 * Long . SIZE ; } c += prefixLength ; long residual = prefixLength - from ; if ( residual > 0 ) { if ( residual > Long . SIZE ) { a += bv . getLong ( from , from + Long . SIZE ) ; residual -= Long . SIZE ; } if ( residual != 0 ) b += bv . getLong ( prefixLength - residual , prefixLength ) ; } a -= b ; a -= c ; a ^= ( c > > > 43 ) ; b -= c ; b -= a ; b ^= ( a << 9 ) ; c -= a ; c -= b ; c ^= ( b > > > 8 ) ; a -= b ; a -= c ; a ^= ( c > > > 38 ) ; b -= c ; b -= a ; b ^= ( a << 23 ) ; c -= a ; c -= b ; c ^= ( b > > > 5 ) ; a -= b ; a -= c ; a ^= ( c > > > 35 ) ; b -= c ; b -= a ; b ^= ( a << 49 ) ; c -= a ; c -= b ; c ^= ( b > > > 11 ) ; a -= b ; a -= c ; a ^= ( c > > > 12 ) ; b -= c ; b -= a ; b ^= ( a << 18 ) ; c -= a ; c -= b ; c ^= ( b > > > 22 ) ; h [ 0 ] = a ; h [ 1 ] = b ; h [ 2 ] = c ; }
constant - time jenkins 64 - bit hashing for any prefix ( all three values produced ) .
