public static long[] preprocessSpooky4(final BitVector bv,final long seed){
  final long length=bv.length();
  if (length < Long.SIZE * 2)   return null;
  final long[] state=new long[4 * (int)(length + Long.SIZE * 2) / (4 * Long.SIZE)];
  long h0, h1, h2, h3;
  h0=seed;
  h1=seed;
  h2=ARBITRARY_BITS;
  h3=ARBITRARY_BITS;
  long remaining=length;
  long pos=0;
  int p=0;
  for (; ; ) {
    h2+=bv.getLong(pos + 0 * Long.SIZE,pos + 1 * Long.SIZE);
    h3+=bv.getLong(pos + 1 * Long.SIZE,pos + 2 * Long.SIZE);
    h2=Long.rotateLeft(h2,50);
    h2+=h3;
    h0^=h2;
    h3=Long.rotateLeft(h3,52);
    h3+=h0;
    h1^=h3;
    h0=Long.rotateLeft(h0,30);
    h0+=h1;
    h2^=h0;
    h1=Long.rotateLeft(h1,41);
    h1+=h2;
    h3^=h1;
    h2=Long.rotateLeft(h2,54);
    h2+=h3;
    h0^=h2;
    h3=Long.rotateLeft(h3,48);
    h3+=h0;
    h1^=h3;
    h0=Long.rotateLeft(h0,38);
    h0+=h1;
    h2^=h0;
    h1=Long.rotateLeft(h1,37);
    h1+=h2;
    h3^=h1;
    h2=Long.rotateLeft(h2,62);
    h2+=h3;
    h0^=h2;
    h3=Long.rotateLeft(h3,34);
    h3+=h0;
    h1^=h3;
    h0=Long.rotateLeft(h0,5);
    h0+=h1;
    h2^=h0;
    h1=Long.rotateLeft(h1,36);
    h1+=h2;
    h3^=h1;
    state[p + 0]=h0;
    state[p + 1]=h1;
    state[p + 2]=h2;
    state[p + 3]=h3;
    p+=4;
    if (remaining >= Long.SIZE * 6) {
      h0+=bv.getLong(pos + 2 * Long.SIZE,pos + 3 * Long.SIZE);
      h1+=bv.getLong(pos + 3 * Long.SIZE,pos + 4 * Long.SIZE);
      remaining-=4 * Long.SIZE;
      pos+=4 * Long.SIZE;
    }
 else     return state;
  }
}

public static long [ ] preprocessSpooky4 ( final BitVector bv , final long seed ) { final long length = bv . length ( ) ; if ( length < Long . SIZE * 2 ) return null ; final long [ ] state = new long [ 4 * ( int ) ( length + Long . SIZE * 2 ) / ( 4 * Long . SIZE ) ] ; long h0 , h1 , h2 , h3 ; h0 = seed ; h1 = seed ; h2 = ARBITRARY_BITS ; h3 = ARBITRARY_BITS ; long remaining = length ; long pos = 0 ; int p = 0 ; for ( ; ; ) { h2 += bv . getLong ( pos + 0 * Long . SIZE , pos + 1 * Long . SIZE ) ; h3 += bv . getLong ( pos + 1 * Long . SIZE , pos + 2 * Long . SIZE ) ; h2 = Long . rotateLeft ( h2 , 50 ) ; h2 += h3 ; h0 ^= h2 ; h3 = Long . rotateLeft ( h3 , 52 ) ; h3 += h0 ; h1 ^= h3 ; h0 = Long . rotateLeft ( h0 , 30 ) ; h0 += h1 ; h2 ^= h0 ; h1 = Long . rotateLeft ( h1 , 41 ) ; h1 += h2 ; h3 ^= h1 ; h2 = Long . rotateLeft ( h2 , 54 ) ; h2 += h3 ; h0 ^= h2 ; h3 = Long . rotateLeft ( h3 , 48 ) ; h3 += h0 ; h1 ^= h3 ; h0 = Long . rotateLeft ( h0 , 38 ) ; h0 += h1 ; h2 ^= h0 ; h1 = Long . rotateLeft ( h1 , 37 ) ; h1 += h2 ; h3 ^= h1 ; h2 = Long . rotateLeft ( h2 , 62 ) ; h2 += h3 ; h0 ^= h2 ; h3 = Long . rotateLeft ( h3 , 34 ) ; h3 += h0 ; h1 ^= h3 ; h0 = Long . rotateLeft ( h0 , 5 ) ; h0 += h1 ; h2 ^= h0 ; h1 = Long . rotateLeft ( h1 , 36 ) ; h1 += h2 ; h3 ^= h1 ; state [ p + 0 ] = h0 ; state [ p + 1 ] = h1 ; state [ p + 2 ] = h2 ; state [ p + 3 ] = h3 ; p += 4 ; if ( remaining >= Long . SIZE * 6 ) { h0 += bv . getLong ( pos + 2 * Long . SIZE , pos + 3 * Long . SIZE ) ; h1 += bv . getLong ( pos + 3 * Long . SIZE , pos + 4 * Long . SIZE ) ; remaining -= 4 * Long . SIZE ; pos += 4 * Long . SIZE ; } else return state ; } }
preprocesses a bit vector so that spookyhash 4 - word - state can be computed in constant time on all prefixes .
