tdb 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.wrongdoc.yml +4 -2
- data/COPYING +497 -160
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +2 -151
- data/HACKING +1 -1
- data/Hash_Functions +17 -6
- data/LICENSE +2 -3
- data/README +4 -4
- data/Rakefile +0 -36
- data/TODO +0 -2
- data/ext/tdb/extconf.rb +1 -0
- data/ext/tdb/hash_functions.c +6 -0
- data/ext/tdb/murmur3.c +230 -0
- data/ext/tdb/rbtdb.h +4 -0
- data/ext/tdb/siphash24.c +328 -0
- data/ext/tdb/tdb.c +71 -56
- data/pkg.mk +175 -0
- data/tdb.gemspec +2 -6
- data/test/test_tdb.rb +24 -2
- data/test/test_tdb_hash_functions.rb +30 -0
- data/test/test_tdb_mt.rb +1 -0
- metadata +47 -58
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
@@ -1,155 +1,6 @@
|
|
1
|
-
# use GNU Make to run tests in parallel, and without depending on RubyGems
|
2
1
|
all::
|
3
|
-
|
4
|
-
RAKE = rake
|
5
|
-
RSYNC = rsync
|
6
|
-
|
7
|
-
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
|
8
|
-
@./GIT-VERSION-GEN
|
9
|
-
-include GIT-VERSION-FILE
|
10
|
-
-include local.mk
|
11
|
-
ifeq ($(DLEXT),) # "so" for Linux
|
12
|
-
DLEXT := $(shell $(RUBY) -rrbconfig -e 'puts Config::CONFIG["DLEXT"]')
|
13
|
-
endif
|
14
|
-
ifeq ($(RUBY_VERSION),)
|
15
|
-
RUBY_VERSION := $(shell $(RUBY) -e 'puts RUBY_VERSION')
|
16
|
-
endif
|
17
|
-
|
18
|
-
install:
|
19
|
-
$(prep_setup_rb)
|
20
|
-
$(RM) -r .install-tmp
|
21
|
-
mkdir .install-tmp
|
22
|
-
$(RUBY) setup.rb all
|
23
|
-
$(RM) $^
|
24
|
-
$(RM) -r .install-tmp
|
25
|
-
$(prep_setup_rb)
|
26
|
-
|
27
|
-
setup_rb_files := .config InstalledFiles
|
28
|
-
prep_setup_rb := @-$(RM) $(setup_rb_files);$(MAKE) -C $(ext) clean
|
29
|
-
|
30
|
-
extdir := ext/tdb
|
31
|
-
clean:
|
32
|
-
-$(MAKE) -C $(extdir) clean
|
33
|
-
$(RM) $(setup_rb_files) $(extdir)/Makefile
|
34
|
-
|
35
|
-
pkg_extra := GIT-VERSION-FILE NEWS ChangeLog LATEST
|
36
|
-
ChangeLog: GIT-VERSION-FILE .wrongdoc.yml
|
37
|
-
wrongdoc prepare
|
38
|
-
|
39
|
-
.manifest: ChangeLog
|
40
|
-
(git ls-files && for i in $@ $(pkg_extra); do echo $$i; done) | \
|
41
|
-
LC_ALL=C sort > $@+
|
42
|
-
cmp $@+ $@ || mv $@+ $@
|
43
|
-
$(RM) $@+
|
44
|
-
|
45
|
-
doc: .document .wrongdoc.yml
|
46
|
-
find lib ext -type f -name '*.rbc' -exec rm -f '{}' ';'
|
47
|
-
$(RM) -r doc
|
48
|
-
wrongdoc all
|
49
|
-
install -m644 COPYING doc/COPYING
|
50
|
-
install -m644 $(shell grep '^[A-Z]' .document) doc/
|
51
|
-
|
52
|
-
ifneq ($(VERSION),)
|
2
|
+
RSYNC_DEST := bogomips.org:/srv/bogomips/ruby-tdb
|
53
3
|
rfproject := qrp
|
54
4
|
rfpackage := tdb
|
55
|
-
pkggem := pkg/$(rfpackage)-$(VERSION).gem
|
56
|
-
pkgtgz := pkg/$(rfpackage)-$(VERSION).tgz
|
57
|
-
release_notes := release_notes-$(VERSION)
|
58
|
-
release_changes := release_changes-$(VERSION)
|
59
|
-
|
60
|
-
release-notes: $(release_notes)
|
61
|
-
release-changes: $(release_changes)
|
62
|
-
$(release_changes):
|
63
|
-
wrongdoc release_changes > $@+
|
64
|
-
$(VISUAL) $@+ && test -s $@+ && mv $@+ $@
|
65
|
-
$(release_notes):
|
66
|
-
wrongdoc release_notes > $@+
|
67
|
-
$(VISUAL) $@+ && test -s $@+ && mv $@+ $@
|
68
|
-
|
69
|
-
# ensures we're actually on the tagged $(VERSION), only used for release
|
70
|
-
verify:
|
71
|
-
test x"$(shell umask)" = x0022
|
72
|
-
git rev-parse --verify refs/tags/v$(VERSION)^{}
|
73
|
-
git diff-index --quiet HEAD^0
|
74
|
-
test `git rev-parse --verify HEAD^0` = \
|
75
|
-
`git rev-parse --verify refs/tags/v$(VERSION)^{}`
|
76
|
-
|
77
|
-
fix-perms:
|
78
|
-
-git ls-tree -r HEAD | awk '/^100644 / {print $$NF}' | xargs chmod 644
|
79
|
-
-git ls-tree -r HEAD | awk '/^100755 / {print $$NF}' | xargs chmod 755
|
80
|
-
|
81
|
-
gem: $(pkggem)
|
82
|
-
|
83
|
-
install-gem: $(pkggem)
|
84
|
-
gem install $(CURDIR)/$<
|
85
|
-
|
86
|
-
$(pkggem): .manifest fix-perms
|
87
|
-
gem build $(rfpackage).gemspec
|
88
|
-
mkdir -p pkg
|
89
|
-
mv $(@F) $@
|
90
|
-
|
91
|
-
$(pkgtgz): distdir = $(basename $@)
|
92
|
-
$(pkgtgz): HEAD = v$(VERSION)
|
93
|
-
$(pkgtgz): .manifest fix-perms
|
94
|
-
@test -n "$(distdir)"
|
95
|
-
$(RM) -r $(distdir)
|
96
|
-
mkdir -p $(distdir)
|
97
|
-
tar cf - `cat .manifest` | (cd $(distdir) && tar xf -)
|
98
|
-
cd pkg && tar cf - $(basename $(@F)) | gzip -9 > $(@F)+
|
99
|
-
mv $@+ $@
|
100
|
-
|
101
|
-
package: $(pkgtgz) $(pkggem)
|
102
|
-
|
103
|
-
test-release: verify package $(release_notes) $(release_changes)
|
104
|
-
release: verify package $(release_notes) $(release_changes)
|
105
|
-
# make tgz release on RubyForge
|
106
|
-
rubyforge add_release -f -n $(release_notes) -a $(release_changes) \
|
107
|
-
$(rfproject) $(rfpackage) $(VERSION) $(pkgtgz)
|
108
|
-
# push gem to RubyGems.org
|
109
|
-
gem push $(pkggem)
|
110
|
-
# in case of gem downloads from RubyForge releases page
|
111
|
-
-rubyforge add_file \
|
112
|
-
$(rfproject) $(rfpackage) $(VERSION) $(pkggem)
|
113
|
-
$(RAKE) raa_update VERSION=$(VERSION)
|
114
|
-
$(RAKE) publish_news VERSION=$(VERSION)
|
115
|
-
else
|
116
|
-
gem install-gem: GIT-VERSION-FILE
|
117
|
-
$(MAKE) $@ VERSION=$(GIT_VERSION)
|
118
|
-
endif
|
119
|
-
|
120
|
-
ext := $(extdir)/tdb_ext.$(DLEXT)
|
121
|
-
$(extdir)/Makefile: $(extdir)/extconf.rb
|
122
|
-
cd $(@D) && $(RUBY) extconf.rb
|
123
|
-
|
124
|
-
c_files := $(wildcard $(extdir)/*.[ch] $(extdir)/*/*.h)
|
125
|
-
$(ext): $(c_files) $(extdir)/Makefile
|
126
|
-
$(MAKE) -C $(@D)
|
127
|
-
|
128
|
-
all:: test
|
129
|
-
|
130
|
-
build: $(ext)
|
131
|
-
test_units := $(wildcard test/test_*.rb)
|
132
|
-
test: test-unit
|
133
|
-
test-unit: $(test_units)
|
134
|
-
$(test_units): build
|
135
|
-
$(RUBY) -I lib:$(extdir) $@
|
136
|
-
|
137
|
-
# this requires GNU coreutils variants
|
138
|
-
publish_doc:
|
139
|
-
-git set-file-times
|
140
|
-
$(MAKE) doc
|
141
|
-
find doc/images -type f | \
|
142
|
-
TZ=UTC xargs touch -d '1970-01-01 00:00:06' doc/rdoc.css
|
143
|
-
$(MAKE) doc_gz
|
144
|
-
chmod 644 $$(find doc -type f)
|
145
|
-
$(RSYNC) -av doc/ bogomips.org:/srv/bogomips/ruby-tdb/
|
146
|
-
git ls-files | xargs touch
|
147
|
-
|
148
|
-
# Create gzip variants of the same timestamp as the original so nginx
|
149
|
-
# "gzip_static on" can serve the gzipped versions directly.
|
150
|
-
doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.\(gif\|jpg\|png\|gz\)$$')
|
151
|
-
doc_gz:
|
152
|
-
for i in $(docs); do \
|
153
|
-
gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
|
154
5
|
|
155
|
-
|
6
|
+
include pkg.mk
|
data/HACKING
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
=== Code Compatibility
|
4
4
|
|
5
|
-
We target Ruby 1.9.
|
5
|
+
We target C Ruby 1.9.3+ and (time permitting) Rubinius and their respective C
|
6
6
|
APIs.
|
7
7
|
|
8
8
|
All of our C code should be compatible with all reasonably modern Unices
|
data/Hash_Functions
CHANGED
@@ -19,15 +19,27 @@ corruption, so don't do it.
|
|
19
19
|
{lookup3 hash}[http://www.burtleburtle.net/bob/c/lookup3.c].
|
20
20
|
<code>:hash => :jenkins_lookup3</code>
|
21
21
|
|
22
|
+
== SipHash
|
23
|
+
|
24
|
+
https://en.wikipedia.org/wiki/Sip_Hash
|
25
|
+
https://131002.net/siphash/
|
26
|
+
|
27
|
+
Currently (as of Ruby 2.1) the favored hash in Ruby for hash-flooding
|
28
|
+
protection.
|
29
|
+
|
30
|
+
* :siphash24 - the reference implementation
|
31
|
+
|
22
32
|
== Murmur family
|
23
33
|
|
24
34
|
The {Murmur}[https://sites.google.com/site/murmurhash/] family of hashes
|
25
|
-
are supported by Ruby TDB.
|
26
|
-
|
27
|
-
|
28
|
-
designed with x86 and x86_64 in mind (they may crash or not work on
|
35
|
+
are supported by Ruby TDB. Most of these are not endian-neutral so
|
36
|
+
databases are no compatible between machines of different endianness and
|
37
|
+
were designed with x86 and x86_64 in mind (they may crash or not work on
|
29
38
|
other architectures).
|
30
39
|
|
40
|
+
* :murmur3a - The latest 32-bit version optimized for x86
|
41
|
+
https://code.google.com/p/smhasher/wiki/MurmurHash3
|
42
|
+
|
31
43
|
* :murmur2 - the simple and fast implementation
|
32
44
|
|
33
45
|
* :murmur2a - words of the author:
|
@@ -61,7 +73,6 @@ other architectures).
|
|
61
73
|
|
62
74
|
== Bernstein hashes
|
63
75
|
|
64
|
-
* :djb3 -
|
65
|
-
See http://www.cse.yorku.ca/~oz/hash.html
|
76
|
+
* :djb3 - See http://www.cse.yorku.ca/~oz/hash.html
|
66
77
|
|
67
78
|
* :djb2 - See http://www.cse.yorku.ca/~oz/hash.html
|
data/LICENSE
CHANGED
@@ -4,7 +4,7 @@ revision control for names and email addresses of all of them.
|
|
4
4
|
This library is free software; you can redistribute it and/or modify it
|
5
5
|
under the terms of the GNU Lesser General Public License as published by
|
6
6
|
the Free Software Foundation; either version
|
7
|
-
{
|
7
|
+
{2.1}[https://www.gnu.org/licenses/lgpl-2.1.txt] of the License, or (at
|
8
8
|
your option) any later version.
|
9
9
|
|
10
10
|
Ruby tdb is distributed in the hope that it will be useful, but WITHOUT
|
@@ -13,5 +13,4 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
13
13
|
License for more details.
|
14
14
|
|
15
15
|
You should have received a copy of the GNU Lesser General Public License
|
16
|
-
along with Ruby tdb; if not,
|
17
|
-
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
16
|
+
along with Ruby tdb; if not, see [https://www.gnu.org/licenses/].
|
data/README
CHANGED
@@ -8,8 +8,8 @@ write to the same databases used by Samba!
|
|
8
8
|
== Features
|
9
9
|
|
10
10
|
* Concurrent reader and writer processes may safely operate on the
|
11
|
-
same file. This is great for MRI
|
12
|
-
|
11
|
+
same file. This is great for MRI where multi-core performance
|
12
|
+
is easiest to achieve with processes and not threads.
|
13
13
|
|
14
14
|
* Fork-safe, you may fork and share the same TDB object in your parent
|
15
15
|
and child processes.
|
@@ -70,13 +70,13 @@ Or if you have a non-standard prefix that linkers normally do not search:
|
|
70
70
|
You can get the latest source via git from the following locations
|
71
71
|
(these versions may not be stable):
|
72
72
|
|
73
|
-
git://
|
73
|
+
git://bogomips.org/ruby-tdb.git
|
74
74
|
git://repo.or.cz/ruby-tdb.git (mirror)
|
75
75
|
|
76
76
|
You may browse the code from the web and download the latest snapshot
|
77
77
|
tarballs here:
|
78
78
|
|
79
|
-
* http://
|
79
|
+
* http://bogomips.org/ruby-tdb.git (cgit)
|
80
80
|
* http://repo.or.cz/w/ruby-tdb.git (gitweb)
|
81
81
|
|
82
82
|
See the HACKING guide on how to contribute and build prerelease gems
|
data/Rakefile
CHANGED
@@ -1,37 +1 @@
|
|
1
1
|
# -*- encoding: binary -*-
|
2
|
-
desc "post to RAA"
|
3
|
-
task :raa_update do
|
4
|
-
require 'net/http'
|
5
|
-
require 'net/netrc'
|
6
|
-
rc = Net::Netrc.locate('tdb-raa') or abort "~/.netrc not found"
|
7
|
-
password = rc.password
|
8
|
-
|
9
|
-
s = Gem::Specification.load('tdb.gemspec')
|
10
|
-
desc = [ s.description.strip ]
|
11
|
-
desc << ""
|
12
|
-
desc << "* #{s.email}"
|
13
|
-
desc << "* #{git_url}"
|
14
|
-
desc << "* #{cgit_url}"
|
15
|
-
desc = desc.join("\n")
|
16
|
-
uri = URI.parse('http://raa.ruby-lang.org/regist.rhtml')
|
17
|
-
form = {
|
18
|
-
:name => s.name,
|
19
|
-
:short_description => s.summary,
|
20
|
-
:version => s.version.to_s,
|
21
|
-
:status => 'experimental',
|
22
|
-
:owner => s.authors.first,
|
23
|
-
:email => s.email,
|
24
|
-
:category_major => 'Library',
|
25
|
-
:category_minor => 'Database',
|
26
|
-
:url => s.homepage,
|
27
|
-
:download => 'http://bogomips.org/ruby-tdb/files/',
|
28
|
-
:license => "LGPL",
|
29
|
-
:description_style => 'Plain',
|
30
|
-
:description => desc,
|
31
|
-
:pass => password,
|
32
|
-
:submit => 'Update',
|
33
|
-
}
|
34
|
-
res = Net::HTTP.post_form(uri, form)
|
35
|
-
p res
|
36
|
-
puts res.body
|
37
|
-
end
|
data/TODO
CHANGED
data/ext/tdb/extconf.rb
CHANGED
data/ext/tdb/hash_functions.c
CHANGED
@@ -10,12 +10,15 @@ static VALUE fn(VALUE self,VALUE str) \
|
|
10
10
|
return UINT2NUM(rbtdb_##fn(&data)); \
|
11
11
|
}
|
12
12
|
|
13
|
+
HASH_FN(siphash24)
|
13
14
|
HASH_FN(murmur1)
|
14
15
|
HASH_FN(murmur1_aligned)
|
15
16
|
HASH_FN(murmur2)
|
16
17
|
HASH_FN(murmur2a)
|
17
18
|
HASH_FN(murmur2_neutral)
|
18
19
|
HASH_FN(murmur2_aligned)
|
20
|
+
HASH_FN(murmur3a)
|
21
|
+
HASH_FN(murmur3f)
|
19
22
|
HASH_FN(fnv1a)
|
20
23
|
HASH_FN(djb2)
|
21
24
|
HASH_FN(djb3)
|
@@ -27,12 +30,15 @@ void rbtdb_init_tdb_hash_functions(void)
|
|
27
30
|
VALUE cTDB = rb_const_get(rb_cObject, rb_intern("TDB"));
|
28
31
|
VALUE mHashFunctions = rb_define_module_under(cTDB, "HashFunctions");
|
29
32
|
|
33
|
+
HASH_M(siphash24);
|
30
34
|
HASH_M(murmur1);
|
31
35
|
HASH_M(murmur1_aligned);
|
32
36
|
HASH_M(murmur2);
|
33
37
|
HASH_M(murmur2a);
|
34
38
|
HASH_M(murmur2_neutral);
|
35
39
|
HASH_M(murmur2_aligned);
|
40
|
+
HASH_M(murmur3a);
|
41
|
+
HASH_M(murmur3f);
|
36
42
|
HASH_M(fnv1a);
|
37
43
|
HASH_M(djb2);
|
38
44
|
HASH_M(djb3);
|
data/ext/tdb/murmur3.c
ADDED
@@ -0,0 +1,230 @@
|
|
1
|
+
#include "rbtdb.h"
|
2
|
+
/*
|
3
|
+
* https://sites.google.com/site/murmurhash/
|
4
|
+
*
|
5
|
+
* MurmurHash3 was written by Austin Appleby, and is placed in the public
|
6
|
+
* domain. The author hereby disclaims copyright to this source code.
|
7
|
+
*
|
8
|
+
* Eric Wong trivially ported this to C for Ruby tdb (32-bit versions only)
|
9
|
+
*/
|
10
|
+
|
11
|
+
#include <stdint.h>
|
12
|
+
|
13
|
+
static inline uint32_t rotl32(uint32_t x, int8_t r)
|
14
|
+
{
|
15
|
+
return (x << r) | (x >> (32 - r));
|
16
|
+
}
|
17
|
+
|
18
|
+
#define ROTL32(x,y) rotl32(x,y)
|
19
|
+
|
20
|
+
#define BIG_CONSTANT(x) (x##LLU)
|
21
|
+
|
22
|
+
/* ----------------------------------------------------------------------------
|
23
|
+
* Block read - if your platform needs to do endian-swapping or can only
|
24
|
+
* handle aligned reads, do the conversion here
|
25
|
+
*/
|
26
|
+
|
27
|
+
static inline uint32_t getblock(const uint32_t * p, int i)
|
28
|
+
{
|
29
|
+
return p[i];
|
30
|
+
}
|
31
|
+
|
32
|
+
/* ----------------------------------------------------------------------------
|
33
|
+
* Finalization mix - force all bits of a hash block to avalanche
|
34
|
+
*/
|
35
|
+
|
36
|
+
static inline uint32_t fmix(uint32_t h)
|
37
|
+
{
|
38
|
+
h ^= h >> 16;
|
39
|
+
h *= 0x85ebca6b;
|
40
|
+
h ^= h >> 13;
|
41
|
+
h *= 0xc2b2ae35;
|
42
|
+
h ^= h >> 16;
|
43
|
+
|
44
|
+
return h;
|
45
|
+
}
|
46
|
+
|
47
|
+
unsigned int rbtdb_murmur3a(TDB_DATA * key)
|
48
|
+
{
|
49
|
+
const uint8_t *data = key->dptr;
|
50
|
+
int len = (int)key->dsize;
|
51
|
+
const int nblocks = len / 4;
|
52
|
+
static const uint32_t seed;
|
53
|
+
uint32_t h1 = seed;
|
54
|
+
int i;
|
55
|
+
|
56
|
+
static const uint32_t c1 = 0xcc9e2d51;
|
57
|
+
static const uint32_t c2 = 0x1b873593;
|
58
|
+
|
59
|
+
/* body */
|
60
|
+
const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4);
|
61
|
+
|
62
|
+
for (i = -nblocks; i; i++) {
|
63
|
+
uint32_t k1 = getblock(blocks, i);
|
64
|
+
|
65
|
+
k1 *= c1;
|
66
|
+
k1 = ROTL32(k1, 15);
|
67
|
+
k1 *= c2;
|
68
|
+
|
69
|
+
h1 ^= k1;
|
70
|
+
h1 = ROTL32(h1, 13);
|
71
|
+
h1 = h1 * 5 + 0xe6546b64;
|
72
|
+
}
|
73
|
+
|
74
|
+
/* tail */
|
75
|
+
{
|
76
|
+
const uint8_t *tail = (const uint8_t *)(data + nblocks * 4);
|
77
|
+
uint32_t k1 = 0;
|
78
|
+
|
79
|
+
switch (len & 3) {
|
80
|
+
case 3:
|
81
|
+
k1 ^= tail[2] << 16;
|
82
|
+
case 2:
|
83
|
+
k1 ^= tail[1] << 8;
|
84
|
+
case 1:
|
85
|
+
k1 ^= tail[0];
|
86
|
+
k1 *= c1;
|
87
|
+
k1 = ROTL32(k1, 15);
|
88
|
+
k1 *= c2;
|
89
|
+
h1 ^= k1;
|
90
|
+
};
|
91
|
+
}
|
92
|
+
|
93
|
+
/* finalization */
|
94
|
+
|
95
|
+
h1 ^= len;
|
96
|
+
|
97
|
+
return fmix(h1);
|
98
|
+
}
|
99
|
+
|
100
|
+
static inline uint64_t rotl64(uint64_t x, int8_t r)
|
101
|
+
{
|
102
|
+
return (x << r) | (x >> (64 - r));
|
103
|
+
}
|
104
|
+
|
105
|
+
#define ROTL64(x,y) rotl64(x,y)
|
106
|
+
|
107
|
+
static inline uint64_t getblock64(const uint64_t * p, int i)
|
108
|
+
{
|
109
|
+
return p[i];
|
110
|
+
}
|
111
|
+
|
112
|
+
static inline uint64_t fmix64(uint64_t k)
|
113
|
+
{
|
114
|
+
k ^= k >> 33;
|
115
|
+
k *= BIG_CONSTANT(0xff51afd7ed558ccd);
|
116
|
+
k ^= k >> 33;
|
117
|
+
k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
|
118
|
+
k ^= k >> 33;
|
119
|
+
|
120
|
+
return k;
|
121
|
+
}
|
122
|
+
|
123
|
+
/* this was a 128-bit hash for x86_64, but we only want 32-bits */
|
124
|
+
unsigned int rbtdb_murmur3f(TDB_DATA * key)
|
125
|
+
{
|
126
|
+
const uint8_t *data = key->dptr;
|
127
|
+
int len = (int)key->dsize;
|
128
|
+
const int nblocks = len / 16;
|
129
|
+
static const uint32_t seed;
|
130
|
+
uint64_t h1 = seed;
|
131
|
+
uint64_t h2 = seed;
|
132
|
+
uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
|
133
|
+
uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
|
134
|
+
int i;
|
135
|
+
|
136
|
+
/* body */
|
137
|
+
const uint64_t *blocks = (const uint64_t *)(data);
|
138
|
+
|
139
|
+
for (i = 0; i < nblocks; i++) {
|
140
|
+
uint64_t k1 = getblock64(blocks, i * 2 + 0);
|
141
|
+
uint64_t k2 = getblock64(blocks, i * 2 + 1);
|
142
|
+
|
143
|
+
k1 *= c1;
|
144
|
+
k1 = ROTL64(k1, 31);
|
145
|
+
k1 *= c2;
|
146
|
+
h1 ^= k1;
|
147
|
+
|
148
|
+
h1 = ROTL64(h1, 27);
|
149
|
+
h1 += h2;
|
150
|
+
h1 = h1 * 5 + 0x52dce729;
|
151
|
+
|
152
|
+
k2 *= c2;
|
153
|
+
k2 = ROTL64(k2, 33);
|
154
|
+
k2 *= c1;
|
155
|
+
h2 ^= k2;
|
156
|
+
|
157
|
+
h2 = ROTL64(h2, 31);
|
158
|
+
h2 += h1;
|
159
|
+
h2 = h2 * 5 + 0x38495ab5;
|
160
|
+
}
|
161
|
+
|
162
|
+
/* tail */
|
163
|
+
{
|
164
|
+
const uint8_t *tail = (const uint8_t *)(data + nblocks * 16);
|
165
|
+
|
166
|
+
uint64_t k1 = 0;
|
167
|
+
uint64_t k2 = 0;
|
168
|
+
#define CAST64(x) ((uint64_t)(x))
|
169
|
+
|
170
|
+
switch (len & 15) {
|
171
|
+
case 15:
|
172
|
+
k2 ^= CAST64(tail[14]) << 48;
|
173
|
+
case 14:
|
174
|
+
k2 ^= CAST64(tail[13]) << 40;
|
175
|
+
case 13:
|
176
|
+
k2 ^= CAST64(tail[12]) << 32;
|
177
|
+
case 12:
|
178
|
+
k2 ^= CAST64(tail[11]) << 24;
|
179
|
+
case 11:
|
180
|
+
k2 ^= CAST64(tail[10]) << 16;
|
181
|
+
case 10:
|
182
|
+
k2 ^= CAST64(tail[9]) << 8;
|
183
|
+
case 9:
|
184
|
+
k2 ^= CAST64(tail[8]) << 0;
|
185
|
+
k2 *= c2;
|
186
|
+
k2 = ROTL64(k2, 33);
|
187
|
+
k2 *= c1;
|
188
|
+
h2 ^= k2;
|
189
|
+
|
190
|
+
case 8:
|
191
|
+
k1 ^= CAST64(tail[7]) << 56;
|
192
|
+
case 7:
|
193
|
+
k1 ^= CAST64(tail[6]) << 48;
|
194
|
+
case 6:
|
195
|
+
k1 ^= CAST64(tail[5]) << 40;
|
196
|
+
case 5:
|
197
|
+
k1 ^= CAST64(tail[4]) << 32;
|
198
|
+
case 4:
|
199
|
+
k1 ^= CAST64(tail[3]) << 24;
|
200
|
+
case 3:
|
201
|
+
k1 ^= CAST64(tail[2]) << 16;
|
202
|
+
case 2:
|
203
|
+
k1 ^= CAST64(tail[1]) << 8;
|
204
|
+
case 1:
|
205
|
+
k1 ^= CAST64(tail[0]) << 0;
|
206
|
+
k1 *= c1;
|
207
|
+
k1 = ROTL64(k1, 31);
|
208
|
+
k1 *= c2;
|
209
|
+
h1 ^= k1;
|
210
|
+
};
|
211
|
+
}
|
212
|
+
|
213
|
+
/* finalization */
|
214
|
+
|
215
|
+
h1 ^= len;
|
216
|
+
h2 ^= len;
|
217
|
+
|
218
|
+
h1 += h2;
|
219
|
+
h2 += h1;
|
220
|
+
|
221
|
+
h1 = fmix64(h1);
|
222
|
+
h2 = fmix64(h2);
|
223
|
+
|
224
|
+
h1 += h2;
|
225
|
+
|
226
|
+
/* not needed for 32-bit hash */
|
227
|
+
/* h2 += h1; */
|
228
|
+
|
229
|
+
return (unsigned int)h1; /* truncate to 32-bits */
|
230
|
+
}
|