feat: Add badgerDB support. (#353)
See https://github.com/dgraph-io/badger Slide: https://github.com/gopherchina/conference/blob/master/2018/1.5%20Badger_%20Fast%20Key-Value%20DB%20in%20Go.pdf
This commit is contained in:
23
vendor/github.com/dgryski/go-farm/LICENSE
generated
vendored
Normal file
23
vendor/github.com/dgryski/go-farm/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
As this is a highly derivative work, I have placed it under the same license as the original implementation:
|
||||
|
||||
Copyright (c) 2014-2017 Damian Gryski
|
||||
Copyright (c) 2016-2017 Nicola Asuni - Tecnick.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
203
vendor/github.com/dgryski/go-farm/Makefile
generated
vendored
Normal file
203
vendor/github.com/dgryski/go-farm/Makefile
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
# MAKEFILE
|
||||
#
|
||||
# @author Nicola Asuni <info@tecnick.com>
|
||||
# @link https://github.com/dgryski/go-farm
|
||||
#
|
||||
# This file is intended to be executed in a Linux-compatible system.
|
||||
# It also assumes that the project has been cloned in the right path under GOPATH:
|
||||
# $GOPATH/src/github.com/dgryski/go-farm
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# List special make targets that are not associated with files
|
||||
.PHONY: help all test format fmtcheck vet lint coverage cyclo ineffassign misspell structcheck varcheck errcheck gosimple astscan qa deps clean nuke
|
||||
|
||||
# Use bash as shell (Note: Ubuntu now uses dash which doesn't support PIPESTATUS).
|
||||
SHELL=/bin/bash
|
||||
|
||||
# CVS path (path to the parent dir containing the project)
|
||||
CVSPATH=github.com/dgryski
|
||||
|
||||
# Project owner
|
||||
OWNER=dgryski
|
||||
|
||||
# Project vendor
|
||||
VENDOR=dgryski
|
||||
|
||||
# Project name
|
||||
PROJECT=go-farm
|
||||
|
||||
# Project version
|
||||
VERSION=$(shell cat VERSION)
|
||||
|
||||
# Name of RPM or DEB package
|
||||
PKGNAME=${VENDOR}-${PROJECT}
|
||||
|
||||
# Current directory
|
||||
CURRENTDIR=$(shell pwd)
|
||||
|
||||
# GO lang path
|
||||
ifneq ($(GOPATH),)
|
||||
ifeq ($(findstring $(GOPATH),$(CURRENTDIR)),)
|
||||
# the defined GOPATH is not valid
|
||||
GOPATH=
|
||||
endif
|
||||
endif
|
||||
ifeq ($(GOPATH),)
|
||||
# extract the GOPATH
|
||||
GOPATH=$(firstword $(subst /src/, ,$(CURRENTDIR)))
|
||||
endif
|
||||
|
||||
# --- MAKE TARGETS ---
|
||||
|
||||
# Display general help about this command
|
||||
help:
|
||||
@echo ""
|
||||
@echo "$(PROJECT) Makefile."
|
||||
@echo "GOPATH=$(GOPATH)"
|
||||
@echo "The following commands are available:"
|
||||
@echo ""
|
||||
@echo " make qa : Run all the tests"
|
||||
@echo " make test : Run the unit tests"
|
||||
@echo ""
|
||||
@echo " make format : Format the source code"
|
||||
@echo " make fmtcheck : Check if the source code has been formatted"
|
||||
@echo " make vet : Check for suspicious constructs"
|
||||
@echo " make lint : Check for style errors"
|
||||
@echo " make coverage : Generate the coverage report"
|
||||
@echo " make cyclo : Generate the cyclomatic complexity report"
|
||||
@echo " make ineffassign : Detect ineffectual assignments"
|
||||
@echo " make misspell : Detect commonly misspelled words in source files"
|
||||
@echo " make structcheck : Find unused struct fields"
|
||||
@echo " make varcheck : Find unused global variables and constants"
|
||||
@echo " make errcheck : Check that error return values are used"
|
||||
@echo " make gosimple : Suggest code simplifications"
|
||||
@echo " make astscan : GO AST scanner"
|
||||
@echo ""
|
||||
@echo " make docs : Generate source code documentation"
|
||||
@echo ""
|
||||
@echo " make deps : Get the dependencies"
|
||||
@echo " make clean : Remove any build artifact"
|
||||
@echo " make nuke : Deletes any intermediate file"
|
||||
@echo ""
|
||||
|
||||
|
||||
# Alias for help target
|
||||
all: help
|
||||
|
||||
# Run the unit tests
|
||||
test:
|
||||
@mkdir -p target/test
|
||||
@mkdir -p target/report
|
||||
GOPATH=$(GOPATH) \
|
||||
go test \
|
||||
-covermode=atomic \
|
||||
-bench=. \
|
||||
-race \
|
||||
-cpuprofile=target/report/cpu.out \
|
||||
-memprofile=target/report/mem.out \
|
||||
-mutexprofile=target/report/mutex.out \
|
||||
-coverprofile=target/report/coverage.out \
|
||||
-v ./... | \
|
||||
tee >(PATH=$(GOPATH)/bin:$(PATH) go-junit-report > target/test/report.xml); \
|
||||
test $${PIPESTATUS[0]} -eq 0
|
||||
|
||||
# Format the source code
|
||||
format:
|
||||
@find . -type f -name "*.go" -exec gofmt -s -w {} \;
|
||||
|
||||
# Check if the source code has been formatted
|
||||
fmtcheck:
|
||||
@mkdir -p target
|
||||
@find . -type f -name "*.go" -exec gofmt -s -d {} \; | tee target/format.diff
|
||||
@test ! -s target/format.diff || { echo "ERROR: the source code has not been formatted - please use 'make format' or 'gofmt'"; exit 1; }
|
||||
|
||||
# Check for syntax errors
|
||||
vet:
|
||||
GOPATH=$(GOPATH) go vet .
|
||||
|
||||
# Check for style errors
|
||||
lint:
|
||||
GOPATH=$(GOPATH) PATH=$(GOPATH)/bin:$(PATH) golint .
|
||||
|
||||
# Generate the coverage report
|
||||
coverage:
|
||||
@mkdir -p target/report
|
||||
GOPATH=$(GOPATH) \
|
||||
go tool cover -html=target/report/coverage.out -o target/report/coverage.html
|
||||
|
||||
# Report cyclomatic complexity
|
||||
cyclo:
|
||||
@mkdir -p target/report
|
||||
GOPATH=$(GOPATH) gocyclo -avg ./ | tee target/report/cyclo.txt ; test $${PIPESTATUS[0]} -eq 0
|
||||
|
||||
# Detect ineffectual assignments
|
||||
ineffassign:
|
||||
@mkdir -p target/report
|
||||
GOPATH=$(GOPATH) ineffassign ./ | tee target/report/ineffassign.txt ; test $${PIPESTATUS[0]} -eq 0
|
||||
|
||||
# Detect commonly misspelled words in source files
|
||||
misspell:
|
||||
@mkdir -p target/report
|
||||
GOPATH=$(GOPATH) misspell -error ./ | tee target/report/misspell.txt ; test $${PIPESTATUS[0]} -eq 0
|
||||
|
||||
# Find unused struct fields
|
||||
structcheck:
|
||||
@mkdir -p target/report
|
||||
GOPATH=$(GOPATH) structcheck -a ./ | tee target/report/structcheck.txt
|
||||
|
||||
# Find unused global variables and constants
|
||||
varcheck:
|
||||
@mkdir -p target/report
|
||||
GOPATH=$(GOPATH) varcheck -e ./ | tee target/report/varcheck.txt
|
||||
|
||||
# Check that error return values are used
|
||||
errcheck:
|
||||
@mkdir -p target/report
|
||||
GOPATH=$(GOPATH) errcheck ./ | tee target/report/errcheck.txt
|
||||
|
||||
# Suggest code simplifications
|
||||
gosimple:
|
||||
@mkdir -p target/report
|
||||
GOPATH=$(GOPATH) gosimple ./ | tee target/report/gosimple.txt
|
||||
|
||||
# AST scanner
|
||||
astscan:
|
||||
@mkdir -p target/report
|
||||
GOPATH=$(GOPATH) gas .//*.go | tee target/report/astscan.txt
|
||||
|
||||
# Generate source docs
|
||||
docs:
|
||||
@mkdir -p target/docs
|
||||
nohup sh -c 'GOPATH=$(GOPATH) godoc -http=127.0.0.1:6060' > target/godoc_server.log 2>&1 &
|
||||
wget --directory-prefix=target/docs/ --execute robots=off --retry-connrefused --recursive --no-parent --adjust-extension --page-requisites --convert-links http://127.0.0.1:6060/pkg/github.com/${VENDOR}/${PROJECT}/ ; kill -9 `lsof -ti :6060`
|
||||
@echo '<html><head><meta http-equiv="refresh" content="0;./127.0.0.1:6060/pkg/'${CVSPATH}'/'${PROJECT}'/index.html"/></head><a href="./127.0.0.1:6060/pkg/'${CVSPATH}'/'${PROJECT}'/index.html">'${PKGNAME}' Documentation ...</a></html>' > target/docs/index.html
|
||||
|
||||
# Alias to run all quality-assurance checks
|
||||
qa: fmtcheck test vet lint coverage cyclo ineffassign misspell structcheck varcheck errcheck gosimple astscan
|
||||
|
||||
# --- INSTALL ---
|
||||
|
||||
# Get the dependencies
|
||||
deps:
|
||||
GOPATH=$(GOPATH) go get ./...
|
||||
GOPATH=$(GOPATH) go get github.com/golang/lint/golint
|
||||
GOPATH=$(GOPATH) go get github.com/jstemmer/go-junit-report
|
||||
GOPATH=$(GOPATH) go get github.com/axw/gocov/gocov
|
||||
GOPATH=$(GOPATH) go get github.com/fzipp/gocyclo
|
||||
GOPATH=$(GOPATH) go get github.com/gordonklaus/ineffassign
|
||||
GOPATH=$(GOPATH) go get github.com/client9/misspell/cmd/misspell
|
||||
GOPATH=$(GOPATH) go get github.com/opennota/check/cmd/structcheck
|
||||
GOPATH=$(GOPATH) go get github.com/opennota/check/cmd/varcheck
|
||||
GOPATH=$(GOPATH) go get github.com/kisielk/errcheck
|
||||
GOPATH=$(GOPATH) go get honnef.co/go/tools/cmd/gosimple
|
||||
GOPATH=$(GOPATH) go get github.com/GoASTScanner/gas
|
||||
|
||||
# Remove any build artifact
|
||||
clean:
|
||||
GOPATH=$(GOPATH) go clean ./...
|
||||
|
||||
# Deletes any intermediate file
|
||||
nuke:
|
||||
rm -rf ./target
|
||||
GOPATH=$(GOPATH) go clean -i ./...
|
||||
41
vendor/github.com/dgryski/go-farm/README.md
generated
vendored
Normal file
41
vendor/github.com/dgryski/go-farm/README.md
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# go-farm
|
||||
|
||||
*Google's FarmHash hash functions implemented in Go*
|
||||
|
||||
[](https://github.com/dgryski/go-farm/tree/master)
|
||||
[](https://travis-ci.org/dgryski/go-farm?branch=master)
|
||||
[](https://coveralls.io/github/dgryski/go-farm?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/dgryski/go-farm)
|
||||
[](http://godoc.org/github.com/dgryski/go-farm)
|
||||
|
||||
## Description
|
||||
|
||||
FarmHash, a family of hash functions.
|
||||
|
||||
This is a (mechanical) translation of the non-SSE4/non-AESNI hash functions from Google's FarmHash (https://github.com/google/farmhash).
|
||||
|
||||
|
||||
FarmHash provides hash functions for strings and other data.
|
||||
The functions mix the input bits thoroughly but are not suitable for cryptography.
|
||||
|
||||
All members of the FarmHash family were designed with heavy reliance on previous work by Jyrki Alakuijala, Austin Appleby, Bob Jenkins, and others.
|
||||
|
||||
For more information please consult https://github.com/google/farmhash
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
This application is written in Go language, please refer to the guides in https://golang.org for getting started.
|
||||
|
||||
This project include a Makefile that allows you to test and build the project with simple commands.
|
||||
To see all available options:
|
||||
```bash
|
||||
make help
|
||||
```
|
||||
|
||||
## Running all tests
|
||||
|
||||
Before committing the code, please check if it passes all tests using
|
||||
```bash
|
||||
make qa
|
||||
```
|
||||
1
vendor/github.com/dgryski/go-farm/VERSION
generated
vendored
Normal file
1
vendor/github.com/dgryski/go-farm/VERSION
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
2.0.1
|
||||
30
vendor/github.com/dgryski/go-farm/basics.go
generated
vendored
Normal file
30
vendor/github.com/dgryski/go-farm/basics.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
package farm
|
||||
|
||||
// Some primes between 2^63 and 2^64 for various uses.
|
||||
const k0 uint64 = 0xc3a5c85c97cb3127
|
||||
const k1 uint64 = 0xb492b66fbe98f273
|
||||
const k2 uint64 = 0x9ae16a3b2f90404f
|
||||
|
||||
// Magic numbers for 32-bit hashing. Copied from Murmur3.
|
||||
const c1 uint32 = 0xcc9e2d51
|
||||
const c2 uint32 = 0x1b873593
|
||||
|
||||
// A 32-bit to 32-bit integer hash copied from Murmur3.
|
||||
func fmix(h uint32) uint32 {
|
||||
h ^= h >> 16
|
||||
h *= 0x85ebca6b
|
||||
h ^= h >> 13
|
||||
h *= 0xc2b2ae35
|
||||
h ^= h >> 16
|
||||
return h
|
||||
}
|
||||
|
||||
func mur(a, h uint32) uint32 {
|
||||
// Helper from Murmur3 for combining two 32-bit values.
|
||||
a *= c1
|
||||
a = rotate32(a, 17)
|
||||
a *= c2
|
||||
h ^= a
|
||||
h = rotate32(h, 19)
|
||||
return h*5 + 0xe6546b64
|
||||
}
|
||||
199
vendor/github.com/dgryski/go-farm/farmhashcc.go
generated
vendored
Normal file
199
vendor/github.com/dgryski/go-farm/farmhashcc.go
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
package farm
|
||||
|
||||
// This file provides a 32-bit hash equivalent to CityHash32 (v1.1.1)
|
||||
// and a 128-bit hash equivalent to CityHash128 (v1.1.1). It also provides
|
||||
// a seeded 32-bit hash function similar to CityHash32.
|
||||
|
||||
func hash32Len13to24Seed(s []byte, seed uint32) uint32 {
|
||||
slen := len(s)
|
||||
a := fetch32(s, -4+(slen>>1))
|
||||
b := fetch32(s, 4)
|
||||
c := fetch32(s, slen-8)
|
||||
d := fetch32(s, (slen >> 1))
|
||||
e := fetch32(s, 0)
|
||||
f := fetch32(s, slen-4)
|
||||
h := d*c1 + uint32(slen) + seed
|
||||
a = rotate32(a, 12) + f
|
||||
h = mur(c, h) + a
|
||||
a = rotate32(a, 3) + c
|
||||
h = mur(e, h) + a
|
||||
a = rotate32(a+f, 12) + d
|
||||
h = mur(b^seed, h) + a
|
||||
return fmix(h)
|
||||
}
|
||||
|
||||
func hash32Len0to4(s []byte, seed uint32) uint32 {
|
||||
slen := len(s)
|
||||
b := seed
|
||||
c := uint32(9)
|
||||
for i := 0; i < slen; i++ {
|
||||
v := int8(s[i])
|
||||
b = (b * c1) + uint32(v)
|
||||
c ^= b
|
||||
}
|
||||
return fmix(mur(b, mur(uint32(slen), c)))
|
||||
}
|
||||
|
||||
func hash128to64(x uint128) uint64 {
|
||||
// Murmur-inspired hashing.
|
||||
const mul uint64 = 0x9ddfea08eb382d69
|
||||
a := (x.lo ^ x.hi) * mul
|
||||
a ^= (a >> 47)
|
||||
b := (x.hi ^ a) * mul
|
||||
b ^= (b >> 47)
|
||||
b *= mul
|
||||
return b
|
||||
}
|
||||
|
||||
type uint128 struct {
|
||||
lo uint64
|
||||
hi uint64
|
||||
}
|
||||
|
||||
// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
|
||||
// of any length representable in signed long. Based on City and Murmur.
|
||||
func cityMurmur(s []byte, seed uint128) uint128 {
|
||||
slen := len(s)
|
||||
a := seed.lo
|
||||
b := seed.hi
|
||||
var c uint64
|
||||
var d uint64
|
||||
l := slen - 16
|
||||
if l <= 0 { // len <= 16
|
||||
a = shiftMix(a*k1) * k1
|
||||
c = b*k1 + hashLen0to16(s)
|
||||
if slen >= 8 {
|
||||
d = shiftMix(a + fetch64(s, 0))
|
||||
} else {
|
||||
d = shiftMix(a + c)
|
||||
}
|
||||
} else { // len > 16
|
||||
c = hashLen16(fetch64(s, slen-8)+k1, a)
|
||||
d = hashLen16(b+uint64(slen), c+fetch64(s, slen-16))
|
||||
a += d
|
||||
for {
|
||||
a ^= shiftMix(fetch64(s, 0)*k1) * k1
|
||||
a *= k1
|
||||
b ^= a
|
||||
c ^= shiftMix(fetch64(s, 8)*k1) * k1
|
||||
c *= k1
|
||||
d ^= c
|
||||
s = s[16:]
|
||||
l -= 16
|
||||
if l <= 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
a = hashLen16(a, c)
|
||||
b = hashLen16(d, b)
|
||||
return uint128{a ^ b, hashLen16(b, a)}
|
||||
}
|
||||
|
||||
func cityHash128WithSeed(s []byte, seed uint128) uint128 {
|
||||
slen := len(s)
|
||||
if slen < 128 {
|
||||
return cityMurmur(s, seed)
|
||||
}
|
||||
|
||||
endIdx := ((slen - 1) / 128) * 128
|
||||
lastBlockIdx := endIdx + ((slen - 1) & 127) - 127
|
||||
last := s[lastBlockIdx:]
|
||||
|
||||
// We expect len >= 128 to be the common case. Keep 56 bytes of state:
|
||||
// v, w, x, y, and z.
|
||||
var v1, v2 uint64
|
||||
var w1, w2 uint64
|
||||
x := seed.lo
|
||||
y := seed.hi
|
||||
z := uint64(slen) * k1
|
||||
v1 = rotate64(y^k1, 49)*k1 + fetch64(s, 0)
|
||||
v2 = rotate64(v1, 42)*k1 + fetch64(s, 8)
|
||||
w1 = rotate64(y+z, 35)*k1 + x
|
||||
w2 = rotate64(x+fetch64(s, 88), 53) * k1
|
||||
|
||||
// This is the same inner loop as CityHash64(), manually unrolled.
|
||||
for {
|
||||
x = rotate64(x+y+v1+fetch64(s, 8), 37) * k1
|
||||
y = rotate64(y+v2+fetch64(s, 48), 42) * k1
|
||||
x ^= w2
|
||||
y += v1 + fetch64(s, 40)
|
||||
z = rotate64(z+w1, 33) * k1
|
||||
v1, v2 = weakHashLen32WithSeeds(s, v2*k1, x+w1)
|
||||
w1, w2 = weakHashLen32WithSeeds(s[32:], z+w2, y+fetch64(s, 16))
|
||||
z, x = x, z
|
||||
s = s[64:]
|
||||
x = rotate64(x+y+v1+fetch64(s, 8), 37) * k1
|
||||
y = rotate64(y+v2+fetch64(s, 48), 42) * k1
|
||||
x ^= w2
|
||||
y += v1 + fetch64(s, 40)
|
||||
z = rotate64(z+w1, 33) * k1
|
||||
v1, v2 = weakHashLen32WithSeeds(s, v2*k1, x+w1)
|
||||
w1, w2 = weakHashLen32WithSeeds(s[32:], z+w2, y+fetch64(s, 16))
|
||||
z, x = x, z
|
||||
s = s[64:]
|
||||
slen -= 128
|
||||
if slen < 128 {
|
||||
break
|
||||
}
|
||||
}
|
||||
x += rotate64(v1+z, 49) * k0
|
||||
y = y*k0 + rotate64(w2, 37)
|
||||
z = z*k0 + rotate64(w1, 27)
|
||||
w1 *= 9
|
||||
v1 *= k0
|
||||
// If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
|
||||
for tailDone := 0; tailDone < slen; {
|
||||
tailDone += 32
|
||||
y = rotate64(x+y, 42)*k0 + v2
|
||||
w1 += fetch64(last, 128-tailDone+16)
|
||||
x = x*k0 + w1
|
||||
z += w2 + fetch64(last, 128-tailDone)
|
||||
w2 += v1
|
||||
v1, v2 = weakHashLen32WithSeeds(last[128-tailDone:], v1+z, v2)
|
||||
v1 *= k0
|
||||
}
|
||||
|
||||
// At this point our 56 bytes of state should contain more than
|
||||
// enough information for a strong 128-bit hash. We use two
|
||||
// different 56-byte-to-8-byte hashes to get a 16-byte final result.
|
||||
x = hashLen16(x, v1)
|
||||
y = hashLen16(y+z, w1)
|
||||
return uint128{hashLen16(x+v2, w2) + y,
|
||||
hashLen16(x+w2, y+v2)}
|
||||
}
|
||||
|
||||
func cityHash128(s []byte) uint128 {
|
||||
slen := len(s)
|
||||
if slen >= 16 {
|
||||
return cityHash128WithSeed(s[16:], uint128{fetch64(s, 0), fetch64(s, 8) + k0})
|
||||
}
|
||||
return cityHash128WithSeed(s, uint128{k0, k1})
|
||||
}
|
||||
|
||||
// Fingerprint128 is a 128-bit fingerprint function for byte-slices
|
||||
func Fingerprint128(s []byte) (lo, hi uint64) {
|
||||
h := cityHash128(s)
|
||||
return h.lo, h.hi
|
||||
}
|
||||
|
||||
// Fingerprint64 is a 64-bit fingerprint function for byte-slices
|
||||
func Fingerprint64(s []byte) uint64 {
|
||||
return naHash64(s)
|
||||
}
|
||||
|
||||
// Fingerprint32 is a 32-bit fingerprint function for byte-slices
|
||||
func Fingerprint32(s []byte) uint32 {
|
||||
return Hash32(s)
|
||||
}
|
||||
|
||||
// Hash128 is a 128-bit hash function for byte-slices
|
||||
func Hash128(s []byte) (lo, hi uint64) {
|
||||
return Fingerprint128(s)
|
||||
}
|
||||
|
||||
// Hash128WithSeed is a 128-bit hash function for byte-slices and a 128-bit seed
|
||||
func Hash128WithSeed(s []byte, seed0, seed1 uint64) (lo, hi uint64) {
|
||||
h := cityHash128WithSeed(s, uint128{seed0, seed1})
|
||||
return h.lo, h.hi
|
||||
}
|
||||
102
vendor/github.com/dgryski/go-farm/farmhashmk.go
generated
vendored
Normal file
102
vendor/github.com/dgryski/go-farm/farmhashmk.go
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
package farm
|
||||
|
||||
func hash32Len5to12(s []byte, seed uint32) uint32 {
|
||||
slen := len(s)
|
||||
a := uint32(len(s))
|
||||
b := uint32(len(s) * 5)
|
||||
c := uint32(9)
|
||||
d := b + seed
|
||||
a += fetch32(s, 0)
|
||||
b += fetch32(s, slen-4)
|
||||
c += fetch32(s, ((slen >> 1) & 4))
|
||||
return fmix(seed ^ mur(c, mur(b, mur(a, d))))
|
||||
}
|
||||
|
||||
// Hash32 hashes a byte slice and returns a uint32 hash value
|
||||
func Hash32(s []byte) uint32 {
|
||||
|
||||
slen := len(s)
|
||||
|
||||
if slen <= 24 {
|
||||
if slen <= 12 {
|
||||
if slen <= 4 {
|
||||
return hash32Len0to4(s, 0)
|
||||
}
|
||||
return hash32Len5to12(s, 0)
|
||||
}
|
||||
return hash32Len13to24Seed(s, 0)
|
||||
}
|
||||
|
||||
// len > 24
|
||||
h := uint32(slen)
|
||||
g := c1 * uint32(slen)
|
||||
f := g
|
||||
a0 := rotate32(fetch32(s, slen-4)*c1, 17) * c2
|
||||
a1 := rotate32(fetch32(s, slen-8)*c1, 17) * c2
|
||||
a2 := rotate32(fetch32(s, slen-16)*c1, 17) * c2
|
||||
a3 := rotate32(fetch32(s, slen-12)*c1, 17) * c2
|
||||
a4 := rotate32(fetch32(s, slen-20)*c1, 17) * c2
|
||||
h ^= a0
|
||||
h = rotate32(h, 19)
|
||||
h = h*5 + 0xe6546b64
|
||||
h ^= a2
|
||||
h = rotate32(h, 19)
|
||||
h = h*5 + 0xe6546b64
|
||||
g ^= a1
|
||||
g = rotate32(g, 19)
|
||||
g = g*5 + 0xe6546b64
|
||||
g ^= a3
|
||||
g = rotate32(g, 19)
|
||||
g = g*5 + 0xe6546b64
|
||||
f += a4
|
||||
f = rotate32(f, 19) + 113
|
||||
iters := (slen - 1) / 20
|
||||
for {
|
||||
a := fetch32(s, 0)
|
||||
b := fetch32(s, 4)
|
||||
c := fetch32(s, 8)
|
||||
d := fetch32(s, 12)
|
||||
e := fetch32(s, 16)
|
||||
h += a
|
||||
g += b
|
||||
f += c
|
||||
h = mur(d, h) + e
|
||||
g = mur(c, g) + a
|
||||
f = mur(b+e*c1, f) + d
|
||||
f += g
|
||||
g += f
|
||||
s = s[20:]
|
||||
iters--
|
||||
if iters == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
g = rotate32(g, 11) * c1
|
||||
g = rotate32(g, 17) * c1
|
||||
f = rotate32(f, 11) * c1
|
||||
f = rotate32(f, 17) * c1
|
||||
h = rotate32(h+g, 19)
|
||||
h = h*5 + 0xe6546b64
|
||||
h = rotate32(h, 17) * c1
|
||||
h = rotate32(h+f, 19)
|
||||
h = h*5 + 0xe6546b64
|
||||
h = rotate32(h, 17) * c1
|
||||
return h
|
||||
}
|
||||
|
||||
// Hash32WithSeed hashes a byte slice and a uint32 seed and returns a uint32 hash value
|
||||
func Hash32WithSeed(s []byte, seed uint32) uint32 {
|
||||
slen := len(s)
|
||||
|
||||
if slen <= 24 {
|
||||
if slen >= 13 {
|
||||
return hash32Len13to24Seed(s, seed*c1)
|
||||
}
|
||||
if slen >= 5 {
|
||||
return hash32Len5to12(s, seed)
|
||||
}
|
||||
return hash32Len0to4(s, seed)
|
||||
}
|
||||
h := hash32Len13to24Seed(s[:24], seed^uint32(slen))
|
||||
return mur(Hash32(s[24:])+seed, h)
|
||||
}
|
||||
156
vendor/github.com/dgryski/go-farm/farmhashna.go
generated
vendored
Normal file
156
vendor/github.com/dgryski/go-farm/farmhashna.go
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
package farm
|
||||
|
||||
func shiftMix(val uint64) uint64 {
|
||||
return val ^ (val >> 47)
|
||||
}
|
||||
|
||||
func hashLen16(u, v uint64) uint64 {
|
||||
return hash128to64(uint128{u, v})
|
||||
}
|
||||
|
||||
func hashLen16Mul(u, v, mul uint64) uint64 {
|
||||
// Murmur-inspired hashing.
|
||||
a := (u ^ v) * mul
|
||||
a ^= (a >> 47)
|
||||
b := (v ^ a) * mul
|
||||
b ^= (b >> 47)
|
||||
b *= mul
|
||||
return b
|
||||
}
|
||||
|
||||
func hashLen0to16(s []byte) uint64 {
|
||||
slen := uint64(len(s))
|
||||
if slen >= 8 {
|
||||
mul := k2 + slen*2
|
||||
a := fetch64(s, 0) + k2
|
||||
b := fetch64(s, int(slen-8))
|
||||
c := rotate64(b, 37)*mul + a
|
||||
d := (rotate64(a, 25) + b) * mul
|
||||
return hashLen16Mul(c, d, mul)
|
||||
}
|
||||
|
||||
if slen >= 4 {
|
||||
mul := k2 + slen*2
|
||||
a := fetch32(s, 0)
|
||||
return hashLen16Mul(slen+(uint64(a)<<3), uint64(fetch32(s, int(slen-4))), mul)
|
||||
}
|
||||
if slen > 0 {
|
||||
a := s[0]
|
||||
b := s[slen>>1]
|
||||
c := s[slen-1]
|
||||
y := uint32(a) + (uint32(b) << 8)
|
||||
z := uint32(slen) + (uint32(c) << 2)
|
||||
return shiftMix(uint64(y)*k2^uint64(z)*k0) * k2
|
||||
}
|
||||
return k2
|
||||
}
|
||||
|
||||
// This probably works well for 16-byte strings as well, but it may be overkill
|
||||
// in that case.
|
||||
func hashLen17to32(s []byte) uint64 {
|
||||
slen := len(s)
|
||||
mul := k2 + uint64(slen*2)
|
||||
a := fetch64(s, 0) * k1
|
||||
b := fetch64(s, 8)
|
||||
c := fetch64(s, slen-8) * mul
|
||||
d := fetch64(s, slen-16) * k2
|
||||
return hashLen16Mul(rotate64(a+b, 43)+rotate64(c, 30)+d, a+rotate64(b+k2, 18)+c, mul)
|
||||
}
|
||||
|
||||
// Return a 16-byte hash for 48 bytes. Quick and dirty.
|
||||
// Callers do best to use "random-looking" values for a and b.
|
||||
func weakHashLen32WithSeedsWords(w, x, y, z, a, b uint64) (uint64, uint64) {
|
||||
a += w
|
||||
b = rotate64(b+a+z, 21)
|
||||
c := a
|
||||
a += x
|
||||
a += y
|
||||
b += rotate64(a, 44)
|
||||
return a + z, b + c
|
||||
}
|
||||
|
||||
// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
|
||||
func weakHashLen32WithSeeds(s []byte, a, b uint64) (uint64, uint64) {
|
||||
return weakHashLen32WithSeedsWords(fetch64(s, 0),
|
||||
fetch64(s, 8),
|
||||
fetch64(s, 16),
|
||||
fetch64(s, 24),
|
||||
a,
|
||||
b)
|
||||
}
|
||||
|
||||
// Return an 8-byte hash for 33 to 64 bytes.
|
||||
func hashLen33to64(s []byte) uint64 {
|
||||
slen := len(s)
|
||||
mul := k2 + uint64(slen)*2
|
||||
a := fetch64(s, 0) * k2
|
||||
b := fetch64(s, 8)
|
||||
c := fetch64(s, slen-8) * mul
|
||||
d := fetch64(s, slen-16) * k2
|
||||
y := rotate64(a+b, 43) + rotate64(c, 30) + d
|
||||
z := hashLen16Mul(y, a+rotate64(b+k2, 18)+c, mul)
|
||||
e := fetch64(s, 16) * mul
|
||||
f := fetch64(s, 24)
|
||||
g := (y + fetch64(s, slen-32)) * mul
|
||||
h := (z + fetch64(s, slen-24)) * mul
|
||||
return hashLen16Mul(rotate64(e+f, 43)+rotate64(g, 30)+h, e+rotate64(f+a, 18)+g, mul)
|
||||
}
|
||||
|
||||
func naHash64(s []byte) uint64 {
|
||||
slen := len(s)
|
||||
var seed uint64 = 81
|
||||
if slen <= 32 {
|
||||
if slen <= 16 {
|
||||
return hashLen0to16(s)
|
||||
}
|
||||
return hashLen17to32(s)
|
||||
}
|
||||
if slen <= 64 {
|
||||
return hashLen33to64(s)
|
||||
}
|
||||
// For strings over 64 bytes we loop.
|
||||
// Internal state consists of 56 bytes: v, w, x, y, and z.
|
||||
v := uint128{0, 0}
|
||||
w := uint128{0, 0}
|
||||
x := seed*k2 + fetch64(s, 0)
|
||||
y := seed*k1 + 113
|
||||
z := shiftMix(y*k2+113) * k2
|
||||
// Set end so that after the loop we have 1 to 64 bytes left to process.
|
||||
endIdx := ((slen - 1) / 64) * 64
|
||||
last64Idx := endIdx + ((slen - 1) & 63) - 63
|
||||
last64 := s[last64Idx:]
|
||||
for len(s) > 64 {
|
||||
x = rotate64(x+y+v.lo+fetch64(s, 8), 37) * k1
|
||||
y = rotate64(y+v.hi+fetch64(s, 48), 42) * k1
|
||||
x ^= w.hi
|
||||
y += v.lo + fetch64(s, 40)
|
||||
z = rotate64(z+w.lo, 33) * k1
|
||||
v.lo, v.hi = weakHashLen32WithSeeds(s, v.hi*k1, x+w.lo)
|
||||
w.lo, w.hi = weakHashLen32WithSeeds(s[32:], z+w.hi, y+fetch64(s, 16))
|
||||
x, z = z, x
|
||||
s = s[64:]
|
||||
}
|
||||
mul := k1 + ((z & 0xff) << 1)
|
||||
// Make s point to the last 64 bytes of input.
|
||||
s = last64
|
||||
w.lo += (uint64(slen-1) & 63)
|
||||
v.lo += w.lo
|
||||
w.lo += v.lo
|
||||
x = rotate64(x+y+v.lo+fetch64(s, 8), 37) * mul
|
||||
y = rotate64(y+v.hi+fetch64(s, 48), 42) * mul
|
||||
x ^= w.hi * 9
|
||||
y += v.lo*9 + fetch64(s, 40)
|
||||
z = rotate64(z+w.lo, 33) * mul
|
||||
v.lo, v.hi = weakHashLen32WithSeeds(s, v.hi*mul, x+w.lo)
|
||||
w.lo, w.hi = weakHashLen32WithSeeds(s[32:], z+w.hi, y+fetch64(s, 16))
|
||||
x, z = z, x
|
||||
return hashLen16Mul(hashLen16Mul(v.lo, w.lo, mul)+shiftMix(y)*k0+z, hashLen16Mul(v.hi, w.hi, mul)+x, mul)
|
||||
}
|
||||
|
||||
func naHash64WithSeed(s []byte, seed uint64) uint64 {
|
||||
return naHash64WithSeeds(s, k2, seed)
|
||||
}
|
||||
|
||||
func naHash64WithSeeds(s []byte, seed0, seed1 uint64) uint64 {
|
||||
return hashLen16(naHash64(s)-seed0, seed1)
|
||||
}
|
||||
117
vendor/github.com/dgryski/go-farm/farmhashuo.go
generated
vendored
Normal file
117
vendor/github.com/dgryski/go-farm/farmhashuo.go
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
package farm
|
||||
|
||||
func uoH(x, y, mul uint64, r uint) uint64 {
|
||||
a := (x ^ y) * mul
|
||||
a ^= (a >> 47)
|
||||
b := (y ^ a) * mul
|
||||
return rotate64(b, r) * mul
|
||||
}
|
||||
|
||||
// Hash64WithSeeds hashes a byte slice and two uint64 seeds and returns a uint64 hash value
|
||||
func Hash64WithSeeds(s []byte, seed0, seed1 uint64) uint64 {
|
||||
slen := len(s)
|
||||
if slen <= 64 {
|
||||
return naHash64WithSeeds(s, seed0, seed1)
|
||||
}
|
||||
|
||||
// For strings over 64 bytes we loop.
|
||||
// Internal state consists of 64 bytes: u, v, w, x, y, and z.
|
||||
x := seed0
|
||||
y := seed1*k2 + 113
|
||||
z := shiftMix(y*k2) * k2
|
||||
v := uint128{seed0, seed1}
|
||||
var w uint128
|
||||
u := x - z
|
||||
x *= k2
|
||||
mul := k2 + (u & 0x82)
|
||||
|
||||
// Set end so that after the loop we have 1 to 64 bytes left to process.
|
||||
endIdx := ((slen - 1) / 64) * 64
|
||||
last64Idx := endIdx + ((slen - 1) & 63) - 63
|
||||
last64 := s[last64Idx:]
|
||||
|
||||
for len(s) > 64 {
|
||||
a0 := fetch64(s, 0)
|
||||
a1 := fetch64(s, 8)
|
||||
a2 := fetch64(s, 16)
|
||||
a3 := fetch64(s, 24)
|
||||
a4 := fetch64(s, 32)
|
||||
a5 := fetch64(s, 40)
|
||||
a6 := fetch64(s, 48)
|
||||
a7 := fetch64(s, 56)
|
||||
x += a0 + a1
|
||||
y += a2
|
||||
z += a3
|
||||
v.lo += a4
|
||||
v.hi += a5 + a1
|
||||
w.lo += a6
|
||||
w.hi += a7
|
||||
|
||||
x = rotate64(x, 26)
|
||||
x *= 9
|
||||
y = rotate64(y, 29)
|
||||
z *= mul
|
||||
v.lo = rotate64(v.lo, 33)
|
||||
v.hi = rotate64(v.hi, 30)
|
||||
w.lo ^= x
|
||||
w.lo *= 9
|
||||
z = rotate64(z, 32)
|
||||
z += w.hi
|
||||
w.hi += z
|
||||
z *= 9
|
||||
u, y = y, u
|
||||
|
||||
z += a0 + a6
|
||||
v.lo += a2
|
||||
v.hi += a3
|
||||
w.lo += a4
|
||||
w.hi += a5 + a6
|
||||
x += a1
|
||||
y += a7
|
||||
|
||||
y += v.lo
|
||||
v.lo += x - y
|
||||
v.hi += w.lo
|
||||
w.lo += v.hi
|
||||
w.hi += x - y
|
||||
x += w.hi
|
||||
w.hi = rotate64(w.hi, 34)
|
||||
u, z = z, u
|
||||
s = s[64:]
|
||||
}
|
||||
// Make s point to the last 64 bytes of input.
|
||||
s = last64
|
||||
u *= 9
|
||||
v.hi = rotate64(v.hi, 28)
|
||||
v.lo = rotate64(v.lo, 20)
|
||||
w.lo += (uint64(slen-1) & 63)
|
||||
u += y
|
||||
y += u
|
||||
x = rotate64(y-x+v.lo+fetch64(s, 8), 37) * mul
|
||||
y = rotate64(y^v.hi^fetch64(s, 48), 42) * mul
|
||||
x ^= w.hi * 9
|
||||
y += v.lo + fetch64(s, 40)
|
||||
z = rotate64(z+w.lo, 33) * mul
|
||||
v.lo, v.hi = weakHashLen32WithSeeds(s, v.hi*mul, x+w.lo)
|
||||
w.lo, w.hi = weakHashLen32WithSeeds(s[32:], z+w.hi, y+fetch64(s, 16))
|
||||
return uoH(hashLen16Mul(v.lo+x, w.lo^y, mul)+z-u,
|
||||
uoH(v.hi+y, w.hi+z, k2, 30)^x,
|
||||
k2,
|
||||
31)
|
||||
}
|
||||
|
||||
// Hash64WithSeed hashes a byte slice and a uint64 seed and returns a uint64 hash value
|
||||
func Hash64WithSeed(s []byte, seed uint64) uint64 {
|
||||
if len(s) <= 64 {
|
||||
return naHash64WithSeed(s, seed)
|
||||
}
|
||||
return Hash64WithSeeds(s, 0, seed)
|
||||
}
|
||||
|
||||
// Hash64 hashes a byte slice and returns a uint64 hash value
|
||||
func Hash64(s []byte) uint64 {
|
||||
if len(s) <= 64 {
|
||||
return naHash64(s)
|
||||
}
|
||||
return Hash64WithSeeds(s, 81, 0)
|
||||
}
|
||||
18
vendor/github.com/dgryski/go-farm/platform.go
generated
vendored
Normal file
18
vendor/github.com/dgryski/go-farm/platform.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
package farm
|
||||
|
||||
func rotate32(val uint32, shift uint) uint32 {
|
||||
return ((val >> shift) | (val << (32 - shift)))
|
||||
}
|
||||
|
||||
func rotate64(val uint64, shift uint) uint64 {
|
||||
return ((val >> shift) | (val << (64 - shift)))
|
||||
}
|
||||
|
||||
func fetch32(s []byte, idx int) uint32 {
|
||||
return uint32(s[idx+0]) | uint32(s[idx+1])<<8 | uint32(s[idx+2])<<16 | uint32(s[idx+3])<<24
|
||||
}
|
||||
|
||||
func fetch64(s []byte, idx int) uint64 {
|
||||
return uint64(s[idx+0]) | uint64(s[idx+1])<<8 | uint64(s[idx+2])<<16 | uint64(s[idx+3])<<24 |
|
||||
uint64(s[idx+4])<<32 | uint64(s[idx+5])<<40 | uint64(s[idx+6])<<48 | uint64(s[idx+7])<<56
|
||||
}
|
||||
Reference in New Issue
Block a user