docs: public static int murmurHash3(byte[] data, long nTweak, int hashNum, byte[] object) {
          int h1 = (int)(hashNum * 0xFBA4C795L + nTweak);
          final int c1 = 0xcc9e2d51;
          final int c2 = 0x1b873593;
  
          int numBlocks = (object.length / 4) * 4;
          // body
          for(int i = 0; i < numBlocks; i += 4) {
              int k1 = (object[i] & 0xFF) |
                    ((object[i+1] & 0xFF) << 8) |
                    ((object[i+2] & 0xFF) << 16) |
                    ((object[i+3] & 0xFF) << 24);
              
              k1 *= c1;
              k1 = rotateLeft32(k1, 15);
              k1 *= c2;
  
              h1 ^= k1;
              h1 = rotateLeft32(h1, 13);
              h1 = h1*5+0xe6546b64;
          }
          
          int k1 = 0;
          switch(object.length & 3)
          {
              case 3:
                  k1 ^= (object[numBlocks + 2] & 0xff) << 16;
                  // Fall through.
              case 2:
                  k1 ^= (object[numBlocks + 1] & 0xff) << 8;
                  // Fall through.
              case 1:
                  k1 ^= (object[numBlocks] & 0xff);
                  k1 *= c1; k1 = rotateLeft32(k1, 15); k1 *= c2; h1 ^= k1;
                  // Fall through.
              default:
                  // Do nothing.
                  break;
          }
  
          // finalization
          h1 ^= object.length;
          h1 ^= h1 >>> 16;
          h1 *= 0x85ebca6b;
          h1 ^= h1 >>> 13;
          h1 *= 0xc2b2ae35;
          h1 ^= h1 >>> 16;
          
          return (int)((h1&0xFFFFFFFFL) % (data.length * 8));
      }