code: func NewRingMutex(mutexCount int, hashMaker func() hash.Hash64) *RingMutex {
  	ringMutex := &RingMutex{
  		mutexCount: uint64(mutexCount),
  		// max slice length is bounded by max(int) thus the argument type
  		mutexes: make([]sync.RWMutex, mutexCount, mutexCount),
  		values:  make([]Value, mutexCount, mutexCount),
  		hash: func(address []byte) uint64 {
  			buf := make([]byte, 8)
  			copy(buf, address)
  			return binary.LittleEndian.Uint64(buf)
  		},
  	}
  	if hashMaker != nil {
  		hasherPool := &sync.Pool{
  			New: func() interface{} {
  				return hashMaker()
  			},
  		}
  		ringMutex.hash = func(address []byte) uint64 {
  			h := hasherPool.Get().(hash.Hash64)
  			defer func() {
  				h.Reset()
  				hasherPool.Put(h)
  			}()
  			h.Write(address)
  			return h.Sum64()
  		}
  	}
  	return ringMutex
  }
docs: // Create a RW mutex that provides a pseudo-independent set of mutexes for addresses
  // where the address space is mapped into possibly much smaller set of backing
  // mutexes using the xxhash (non-cryptographic)
  // hash function // modulo size. If some addresses collide modulo size they will be unnecessary
  // contention between those addresses, but you can trade space against contention
  // as desired.