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.
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v0.5.0.GIT
4
+ DEF_VER=v0.6.0
5
5
 
6
6
  LF='
7
7
  '
@@ -1,155 +1,6 @@
1
- # use GNU Make to run tests in parallel, and without depending on RubyGems
2
1
  all::
3
- RUBY = ruby
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
- .PHONY: .FORCE-GIT-VERSION-FILE doc test $(test_units)
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.2 and eventually Rubinius 1.1+ and their respective C
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
@@ -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. MurmurHash3 will be supported as soon as it
26
- becomes finalized. Most of these are not endian-neutral so databases
27
- are no compatible between machines of different endianness and were
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 - The hash currently favored by Bernstein.
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
- {3}[http://www.gnu.org/licenses/lgpl-3.0.txt] of the License, or (at
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, write to the Free Software
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 1.8 and 1.9 where multi-core
12
- performance is easiest to achieve with processes and not threads.
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://git.bogomips.org/ruby-tdb.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://git.bogomips.org/cgit/ruby-tdb.git (cgit)
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
@@ -1,5 +1,3 @@
1
- * port the final Murmur3 hash implementation
2
-
3
1
  * support more TDB-specific features
4
2
 
5
3
  * make it reasonably API-compatible with other DBM bindings
@@ -2,6 +2,7 @@ require 'mkmf'
2
2
 
3
3
  have_func('rb_thread_blocking_region')
4
4
  have_func('rb_thread_call_with_gvl')
5
+ have_func('rb_thread_call_without_gvl', 'ruby/thread.h')
5
6
 
6
7
  dir_config('tdb')
7
8
  have_header('tdb.h') or abort 'tdb.h missing'
@@ -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);
@@ -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
+ }