Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.fasterxml.storemate.shared.hash;
  
  public final class IncrementalMurmur3Hasher extends IncrementalHasher32
  {
      protected final static int c1 = 0xcc9e2d51;
      protected final static int c2 = 0x1b873593;
  	
      protected final static int c3 = 0xe6546b64;
  
     private final int _seed;

    
Number of bytes for which checksum has been calculated
 
     private long _totalBytes;
 
     private int _partialBytes;
     private int _partialByteCount;

    
Currently calculated partial hash value. Note that it will remain valid until reset() is called, so it is possible to calculate partial checksums with the same instance.
 
     private int _currentHash;
 
     public IncrementalMurmur3Hasher() {
         this(.);
     }
 
     public IncrementalMurmur3Hasher(int seed)
     {
          = seed;
         reset();
     }
 
     /*
     /**********************************************************************
     /* Public API
     /**********************************************************************
      */

    
Method for checking number of bytes that have been sent to IncrementalHasher32.update(int) since creation or last call to reset()
 
     @Override
     public long getLength() {
         return ;
     }
 
     @Override
     public int calculateHash()
     {
         /* Since we only retain 'partial' value, we now need to perform
          * finalizations, as expected.
          */
         int h1 = ;
 
         // First: any partial data ("tail") we may have needs to be added
         if ( > 0) {
             int k1 = ;
             k1 *= ;
             k1 = Integer.rotateLeft(k1, 15);
             k1 *= ;
             h1 ^= k1;
         }
 
         // And then finalize the calculation
         h1 ^= (int) ();
 
         // fmix(h1);
         h1 ^= h1 >>> 16;
         h1 *= 0x85ebca6b;
         h1 ^= h1 >>> 13;
         h1 *= 0xc2b2ae35;
         h1 ^= h1 >>> 16;
 
         return h1;
     }
 
     @Override
     public void reset() {
          =  = 0;
          = 0L;
          = ;
     }
 
     @Override
     public void update(byte[] dataint offsetint len)
     {
         if (data == null || offset < 0 || len < 1 || (offset+len) > data.length) {
             if (len == 0) {
                 return;
             }
             throw new IllegalArgumentException();
         }
 
         // We will process all bytes, one way or another, so
         += len;
        // First things first: any partial data to use?
        if ( > 0) {
            int count = _resolvePartial(dataoffsetlen);
            if ((len -= count) == 0) {
                return;
            }
            offset += count;
        }
        // HotSpot seems to like optimizing 'simple' chunks; main loop offlined
        _update(dataoffsetlen);
    }
    private final void _update(byte[] dataint offsetfinal int len)
    {
        int h1 = ;
        final int roundedEnd = offset + (len & 0xfffffffc);  // round down to 4 byte block
        for (; offset < roundedEndoffset += 4) {
//	         	int k1 = _gatherIntLE(data, offset);
            int k1 = (data[offset] & 0xff) | ((data[offset+1] & 0xff) << 8) | ((data[offset+2] & 0xff) << 16) | (data[offset+3] << 24);
            k1 *= ;
            k1 =  Integer.rotateLeft(k1, 15);
            k1 *= ;
            h1 ^= k1;
            h1 =  Integer.rotateLeft(h1, 13);
            h1 = h1*5 + ;
        }
         = h1;
        // and save the tail, if any
        int remainder = len&3;
        if (remainder > 0) {
            _stashTail(dataoffsetremainder);
        }
    }
    /*
    /**********************************************************************
    /* Helper methods
    /**********************************************************************
     */

    
Helper method for resolving existing partial data, before the fast main loop.
    private final int _resolvePartial(byte[] datafinal int offsetfinal int len)
    {
        int ptr = offset;
        final int end = ptr+len;
        // may have 1, 2 or 3 bytes, in LSB
        switch () { // how many bytes have we stashed prior?
        case 1:
            if (ptr >= end) {
                return 0;
            }
             |= ((data[ptr++] & 0xFF) << 8);
            // fall through
        case 2:
            if (ptr >= end) {
                 = 2;
                return (ptr - offset);
            }
             |= ((data[ptr++] & 0xFF) << 16);
            // fall through
        case 3:
            if (ptr >= end) {
                 = 3;
                return (ptr - offset);
            }
             |= ((data[ptr++] & 0xFF) << 24);
            break;
        default:
            throw new IllegalStateException("Partial byte count = "++"; must be (1,3)");
        }
        // good: got a full int32, process:
         = 0;
        int k1 = ;
        k1 *= ;
        k1 = Integer.rotateLeft(k1, 15);
        k1 *= ;
        int h1 = ;
        h1 ^= k1;
        h1 = Integer.rotateLeft(h1, 13);
        h1 = h1*5 + ;
         = h1;
        return (ptr - offset);
    }

    
Helper method for stashing partial data (1-3 bytes) after main loop.
    private final void _stashTail(byte[] dataint offsetint remainder)
    {
         = remainder;
        int k1 = data[offset] & 0xFF;
        if (remainder > 1) {
            k1 |= (data[++offset] & 0xff) << 8;
            if (remainder > 2) {
                k1 |= (data[++offset] & 0xff) << 16;
            }
        }
         = k1;
    }
    protected final static int _gatherIntLE(byte[] dataint index)
    {
        int i = data[index] & 0xFF;
        i |= (data[++index] & 0xFF) << 8;
        i |= (data[++index] & 0xFF) << 16;
        i |= (data[++index] << 24);
        return i;
    }
New to GrepCode? Check out our FAQ X