package murmur3

// http://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/hash/Murmur3_32HashFunction.java

import (
	
	
)

// Make sure interfaces are correctly implemented.
var (
	_ hash.Hash   = new(digest32)
	_ hash.Hash32 = new(digest32)
	_ bmixer      = new(digest32)
)

const (
	c1_32 uint32 = 0xcc9e2d51
	c2_32 uint32 = 0x1b873593
)

// digest32 represents a partial evaluation of a 32 bites hash.
type digest32 struct {
	digest
	h1 uint32 // Unfinalized running hash.
}

// New32 returns new 32-bit hasher
func () hash.Hash32 { return New32WithSeed(0) }

// New32WithSeed returns new 32-bit hasher set with explicit seed value
func ( uint32) hash.Hash32 {
	 := new(digest32)
	.seed = 
	.bmixer = 
	.Reset()
	return 
}

func ( *digest32) () int { return 4 }

func ( *digest32) () { .h1 = .seed }

func ( *digest32) ( []byte) []byte {
	 := .Sum32()
	return append(, byte(>>24), byte(>>16), byte(>>8), byte())
}

// Digest as many blocks as possible.
func ( *digest32) ( []byte) ( []byte) {
	 := .h1

	 := len() / 4
	for  := 0;  < ; ++ {
		 := *(*uint32)(unsafe.Pointer(&[*4]))

		 *= c1_32
		 = ( << 15) | ( >> 17) // rotl32(k1, 15)
		 *= c2_32

		 ^= 
		 = ( << 13) | ( >> 19) // rotl32(h1, 13)
		 = *4 +  + 0xe6546b64
	}
	.h1 = 
	return [*.Size():]
}

func ( *digest32) () ( uint32) {

	 = .h1

	var  uint32
	switch len(.tail) & 3 {
	case 3:
		 ^= uint32(.tail[2]) << 16
		fallthrough
	case 2:
		 ^= uint32(.tail[1]) << 8
		fallthrough
	case 1:
		 ^= uint32(.tail[0])
		 *= c1_32
		 = ( << 15) | ( >> 17) // rotl32(k1, 15)
		 *= c2_32
		 ^= 
	}

	 ^= uint32(.clen)

	 ^=  >> 16
	 *= 0x85ebca6b
	 ^=  >> 13
	 *= 0xc2b2ae35
	 ^=  >> 16

	return 
}

/*
func rotl32(x uint32, r byte) uint32 {
	return (x << r) | (x >> (32 - r))
}
*/

// Sum32 returns the MurmurHash3 sum of data. It is equivalent to the
// following sequence (without the extra burden and the extra allocation):
//     hasher := New32()
//     hasher.Write(data)
//     return hasher.Sum32()
func ( []byte) uint32 { return Sum32WithSeed(, 0) }

// Sum32WithSeed returns the MurmurHash3 sum of data. It is equivalent to the
// following sequence (without the extra burden and the extra allocation):
//     hasher := New32WithSeed(seed)
//     hasher.Write(data)
//     return hasher.Sum32()
func ( []byte,  uint32) uint32 {

	 := 

	 := len() / 4
	var  uintptr
	if len() > 0 {
		 = uintptr(unsafe.Pointer(&[0]))
	}
	 :=  + uintptr(4*)
	for ;  < ;  += 4 {
		 := *(*uint32)(unsafe.Pointer())

		 *= c1_32
		 = ( << 15) | ( >> 17) // rotl32(k1, 15)
		 *= c2_32

		 ^= 
		 = ( << 13) | ( >> 19) // rotl32(h1, 13)
		 = *4 +  + 0xe6546b64
	}

	 := [*4:]

	var  uint32
	switch len() & 3 {
	case 3:
		 ^= uint32([2]) << 16
		fallthrough
	case 2:
		 ^= uint32([1]) << 8
		fallthrough
	case 1:
		 ^= uint32([0])
		 *= c1_32
		 = ( << 15) | ( >> 17) // rotl32(k1, 15)
		 *= c2_32
		 ^= 
	}

	 ^= uint32(len())

	 ^=  >> 16
	 *= 0x85ebca6b
	 ^=  >> 13
	 *= 0xc2b2ae35
	 ^=  >> 16

	return 
}