public static char[] genOffsetBitmap(int[] offsets){
  int lastOffset=offsets[offsets.length - 1];
  int numBlocks=(lastOffset / BITMAP_BLOCK_SZ) + 1;
  int[] blockLengths=new int[numBlocks];
  Arrays.fill(blockLengths,0);
  for (int ix=0; ix < offsets.length; ix++) {
    int val=offsets[ix];
    int blockForVal=val / BITMAP_BLOCK_SZ;
    blockLengths[blockForVal]++;
  }
  int totalSize=numBlocks;
  for (int block=0; block < numBlocks; block++) {
    totalSize+=blockLengths[block];
  }
  char[] encodedBlocks=new char[totalSize];
  int inputIx=0;
  int blockStartIx=0;
  for (int block=0; block < numBlocks; block++) {
    int blockSz=blockLengths[block];
    encodedBlocks[blockStartIx]=(char)blockSz;
    for (int i=0; i < blockSz; i++) {
      encodedBlocks[blockStartIx + i + 1]=(char)(offsets[inputIx + i] % BITMAP_BLOCK_SZ);
    }
    inputIx+=blockSz;
    blockStartIx+=blockSz + 1;
  }
  return encodedBlocks;
}

public static char [ ] genOffsetBitmap ( int [ ] offsets ) { int lastOffset = offsets [ offsets . length - 1 ] ; int numBlocks = ( lastOffset / BITMAP_BLOCK_SZ ) + 1 ; int [ ] blockLengths = new int [ numBlocks ] ; Arrays . fill ( blockLengths , 0 ) ; for ( int ix = 0 ; ix < offsets . length ; ix ++ ) { int val = offsets [ ix ] ; int blockForVal = val / BITMAP_BLOCK_SZ ; blockLengths [ blockForVal ] ++ ; } int totalSize = numBlocks ; for ( int block = 0 ; block < numBlocks ; block ++ ) { totalSize += blockLengths [ block ] ; } char [ ] encodedBlocks = new char [ totalSize ] ; int inputIx = 0 ; int blockStartIx = 0 ; for ( int block = 0 ; block < numBlocks ; block ++ ) { int blockSz = blockLengths [ block ] ; encodedBlocks [ blockStartIx ] = ( char ) blockSz ; for ( int i = 0 ; i < blockSz ; i ++ ) { encodedBlocks [ blockStartIx + i + 1 ] = ( char ) ( offsets [ inputIx + i ] % BITMAP_BLOCK_SZ ) ; } inputIx += blockSz ; blockStartIx += blockSz + 1 ; } return encodedBlocks ; }
encodes the bitmap in blocks of offsets . within each block , the bits are stored as absolute offsets from the start of the block .
