sparsehash 0.1.0

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/README ADDED
@@ -0,0 +1,74 @@
1
+ = sparsehash
2
+
3
+ Copyright (c) 2009 SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
4
+
5
+ == Description
6
+
7
+ Ruby bindings for Google Sparse Hash.
8
+
9
+ see {Google Sparse Hash}[http://goog-sparsehash.sourceforge.net/].
10
+
11
+ == Install
12
+
13
+ gem install sparsehash
14
+
15
+ == Example
16
+
17
+ require 'sparsehash'
18
+
19
+ map = Sparsehash::SparseHashMap.new
20
+ map['foo'] = 'bar'
21
+ map['zoo'] = 'baz'
22
+
23
+ map.each do |k, v|
24
+ puts "#{k}=#{v}"
25
+ end
26
+
27
+ set = Sparsehash::SparseHashSet.new
28
+ set << 'foo'
29
+ set << 'bar'
30
+
31
+ set.each do |v|
32
+ puts v
33
+ end
34
+
35
+ == Performance
36
+
37
+ link:memory.png
38
+ link:time.png
39
+
40
+ == Project Page
41
+
42
+ http://rubyforge.org/projects/sparsehash
43
+
44
+ == Source Code
45
+
46
+ http://coderepos.org/share/browser/lang/ruby/ruby-sparsehash
47
+
48
+ == License
49
+
50
+ Copyright (c) 2009 SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
51
+ All rights reserved.
52
+
53
+ Redistribution and use in source and binary forms, with or without modification,
54
+ are permitted provided that the following conditions are met:
55
+
56
+ * Redistributions of source code must retain the above copyright notice,
57
+ this list of conditions and the following disclaimer.
58
+ * Redistributions in binary form must reproduce the above copyright notice,
59
+ this list of conditions and the following disclaimer in the documentation
60
+ and/or other materials provided with the distribution.
61
+ * The names of its contributors may not be used to endorse or promote products
62
+ derived from this software without specific prior written permission.
63
+
64
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
65
+ ANY EXPRESS OR IMPLIED WARRANTIES,
66
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
67
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
68
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
69
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
70
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
71
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
72
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
74
+ DAMAGE.
data/etc/anymap.rb ADDED
@@ -0,0 +1,34 @@
1
+ # * Sparsehash::SparseHashMap
2
+ # * Sparsehash::DenseHashMap
3
+ # * STL::Map
4
+ # * GNU::HashMap (gcc only)
5
+ #
6
+ # (include Enumerable)
7
+ class AnyMap
8
+ def [](key)
9
+ end
10
+
11
+ def []=(key, value)
12
+ end
13
+
14
+ def each
15
+ end
16
+
17
+ def erase(key)
18
+ end
19
+
20
+ def delete(key)
21
+ end
22
+
23
+ def size
24
+ end
25
+
26
+ def length
27
+ end
28
+
29
+ def empty?
30
+ end
31
+
32
+ def clear
33
+ end
34
+ end
data/etc/anyset.rb ADDED
@@ -0,0 +1,34 @@
1
+ # * Sparsehash::SparseHashSet
2
+ # * Sparsehash::DenseHashSet
3
+ # * STL::Set
4
+ # * GNU::HashMap (gcc only)
5
+ #
6
+ # (include Enumerable)
7
+ class AnySet
8
+ def insert(value)
9
+ end
10
+
11
+ def <<(value)
12
+ end
13
+
14
+ def each
15
+ end
16
+
17
+ def erase(value)
18
+ end
19
+
20
+ def delete(value)
21
+ end
22
+
23
+ def size
24
+ end
25
+
26
+ def length
27
+ end
28
+
29
+ def empty?
30
+ end
31
+
32
+ def clear
33
+ end
34
+ end
data/ext/extconf.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+
3
+ if have_library('stdc++')
4
+ create_makefile('sparsehash')
5
+ end
@@ -0,0 +1,429 @@
1
+ #include <google/sparse_hash_map>
2
+ #include <google/dense_hash_map>
3
+ #include <google/sparse_hash_set>
4
+ #include <google/dense_hash_set>
5
+
6
+ #include <map>
7
+ #include <set>
8
+
9
+ #ifdef __GNUC__
10
+ #include <ext/hash_map>
11
+ #include <ext/hash_set>
12
+ namespace std {
13
+ using namespace __gnu_cxx;
14
+ }
15
+ #endif
16
+
17
+ #include "sparsehash_internal.h"
18
+
19
+ namespace {
20
+
21
+ struct sparsehash_equal_key {
22
+ bool operator() (const VALUE &x, const VALUE &y) const {
23
+ return (rb_funcall(x, rb_intern("=="), 1, y) == Qtrue);
24
+ }
25
+ };
26
+
27
+ struct sparsehash_hash {
28
+ size_t operator() (const VALUE &x) const {
29
+ VALUE hash = rb_funcall(x, rb_intern("hash"), 0);
30
+ return NUM2INT(hash);
31
+ }
32
+ };
33
+
34
+ struct stl_key_compare {
35
+ bool operator() (const VALUE &x, const VALUE &y) const {
36
+ VALUE hash_x = rb_funcall(x, rb_intern("hash"), 0);
37
+ VALUE hash_y = rb_funcall(y, rb_intern("hash"), 0);
38
+ int i_hash_x = NUM2INT(hash_x);
39
+ int i_hash_y = NUM2INT(hash_y);
40
+
41
+ return (i_hash_x < i_hash_y);
42
+ }
43
+ };
44
+
45
+ typedef google::sparse_hash_map<VALUE, VALUE, sparsehash_hash, sparsehash_equal_key> SHMap;
46
+ typedef google::dense_hash_map<VALUE, VALUE, sparsehash_hash, sparsehash_equal_key> DHMap;
47
+ typedef google::sparse_hash_set<VALUE, sparsehash_hash, sparsehash_equal_key> SHSet;
48
+ typedef google::dense_hash_set<VALUE, sparsehash_hash, sparsehash_equal_key> DHSet;
49
+ typedef std::map<VALUE, VALUE, stl_key_compare> STLMap;
50
+ typedef std::set<VALUE, stl_key_compare> STLSet;
51
+
52
+ #ifdef __GNUC__
53
+ typedef std::hash_map<VALUE, VALUE, sparsehash_hash, sparsehash_equal_key> GNUHashMap;
54
+ typedef std::hash_set<VALUE, sparsehash_hash, sparsehash_equal_key> GNUHashSet;
55
+ #endif
56
+
57
+ template <class T>
58
+ void sparsehash_initialize(T *x) {
59
+ };
60
+
61
+ template <>
62
+ void sparsehash_initialize<SHMap>(SHMap *x) {
63
+ x->set_deleted_key(Qnil);
64
+ }
65
+
66
+ template <>
67
+ void sparsehash_initialize<SHSet>(SHSet *x) {
68
+ x->set_deleted_key(Qnil);
69
+ }
70
+
71
+ template <>
72
+ void sparsehash_initialize<DHMap>(DHMap *x) {
73
+ x->set_empty_key((VALUE) NULL);
74
+ x->set_deleted_key(Qnil);
75
+ }
76
+
77
+ template <>
78
+ void sparsehash_initialize<DHSet>(DHSet *x) {
79
+ x->set_empty_key((VALUE) NULL);
80
+ x->set_deleted_key(Qnil);
81
+ }
82
+
83
+ template <class T>
84
+ void sparsehash_validate_key(VALUE &x) {
85
+ }
86
+
87
+ template <>
88
+ void sparsehash_validate_key<SHMap>(VALUE &x) {
89
+ if (NIL_P(x)) {
90
+ rb_raise(rb_eArgError, "Invalid key: nil");
91
+ }
92
+ }
93
+
94
+ template <>
95
+ void sparsehash_validate_key<SHSet>(VALUE &x) {
96
+ if (NIL_P(x)) {
97
+ rb_raise(rb_eArgError, "Invalid key: nil");
98
+ }
99
+ }
100
+
101
+ template <>
102
+ void sparsehash_validate_key<DHMap>(VALUE &x) {
103
+ if (!x) {
104
+ rb_raise(rb_eArgError, "Invalid key: false");
105
+ } else if(NIL_P(x)) {
106
+ rb_raise(rb_eArgError, "Invalid key: nil");
107
+ }
108
+ }
109
+
110
+ template <>
111
+ void sparsehash_validate_key<DHSet>(VALUE &x) {
112
+ if (!x) {
113
+ rb_raise(rb_eArgError, "Invalid key: false");
114
+ } else if(NIL_P(x)) {
115
+ rb_raise(rb_eArgError, "Invalid key: nil");
116
+ }
117
+ }
118
+
119
+ template <class T>
120
+ struct SparsehashMap {
121
+ T *m;
122
+
123
+ static void mark(SparsehashMap<T> *p) {
124
+ if (!p->m) {
125
+ return;
126
+ }
127
+
128
+ T *m = p->m;
129
+
130
+ for(typename T::iterator i = m->begin(); i != m->end(); i++) {
131
+ rb_gc_mark(i->first);
132
+ rb_gc_mark(i->second);
133
+ }
134
+ }
135
+
136
+ static void free(SparsehashMap<T> *p) {
137
+ if (p->m) {
138
+ delete p->m;
139
+ }
140
+
141
+ delete p;
142
+ }
143
+
144
+ static VALUE alloc(VALUE klass) {
145
+ SparsehashMap<T> *p;
146
+
147
+ p = new SparsehashMap<T>;
148
+ p->m = NULL;
149
+
150
+ return Data_Wrap_Struct(klass, &mark, &free, p);
151
+ }
152
+
153
+ static VALUE initialize(VALUE self) {
154
+ SparsehashMap<T> *p;
155
+
156
+ Data_Get_Struct(self, SparsehashMap<T>, p);
157
+ p->m = new T;
158
+ sparsehash_initialize<T>(p->m);
159
+
160
+ return Qnil;
161
+ }
162
+
163
+ static VALUE get(VALUE self, VALUE key) {
164
+ SparsehashMap<T> *p;
165
+
166
+ sparsehash_validate_key<T>(key);
167
+ Data_Get_Struct(self, SparsehashMap<T>, p);
168
+ T &m = *(p->m);
169
+
170
+ VALUE value = m[key];
171
+
172
+ return(value ? value : Qnil);
173
+ }
174
+
175
+ static VALUE set(VALUE self, VALUE key, VALUE value) {
176
+ SparsehashMap<T> *p;
177
+
178
+ sparsehash_validate_key<T>(key);
179
+ Data_Get_Struct(self, SparsehashMap<T>, p);
180
+ T &m = *(p->m);
181
+
182
+ m[key] = value;
183
+
184
+ return value;
185
+ }
186
+
187
+ static VALUE each0(VALUE args) {
188
+ return rb_yield(args);
189
+ }
190
+
191
+ static VALUE each(VALUE self) {
192
+ SparsehashMap<T> *p;
193
+
194
+ rb_need_block();
195
+
196
+ Data_Get_Struct(self, SparsehashMap<T>, p);
197
+ T &m = *(p->m);
198
+ int status = 0;
199
+
200
+ for(typename T::iterator i = m.begin(); i != m.end(); i++) {
201
+ VALUE args = rb_ary_new3(2, i->first, i->second);
202
+
203
+ rb_protect(each0, args, &status);
204
+
205
+ if (status != 0) {
206
+ break;
207
+ }
208
+ }
209
+
210
+ if (status != 0) {
211
+ rb_jump_tag(status);
212
+ }
213
+
214
+ return self;
215
+ }
216
+
217
+ static VALUE erase(VALUE self, VALUE key) {
218
+ SparsehashMap<T> *p;
219
+
220
+ sparsehash_validate_key<T>(key);
221
+ Data_Get_Struct(self, SparsehashMap<T>, p);
222
+ T &m = *(p->m);
223
+
224
+ VALUE value = m[key];
225
+ m.erase(key);
226
+
227
+ return(value ? value : Qnil);
228
+ }
229
+
230
+ static VALUE size(VALUE self) {
231
+ SparsehashMap<T> *p;
232
+
233
+ Data_Get_Struct(self, SparsehashMap<T>, p);
234
+ T &m = *(p->m);
235
+
236
+ return LONG2NUM(m.size());
237
+ }
238
+
239
+ static VALUE empty(VALUE self) {
240
+ SparsehashMap<T> *p;
241
+
242
+ Data_Get_Struct(self, SparsehashMap<T>, p);
243
+ T &m = *(p->m);
244
+
245
+ return m.empty() ? Qtrue : Qfalse;
246
+ }
247
+
248
+ static VALUE clear(VALUE self) {
249
+ SparsehashMap<T> *p;
250
+
251
+ Data_Get_Struct(self, SparsehashMap<T>, p);
252
+ T &m = *(p->m);
253
+ m.clear();
254
+
255
+ return self;
256
+ }
257
+
258
+ static void init(VALUE &module, const char *name) {
259
+ VALUE rb_cMap = rb_define_class_under(module, name, rb_cObject);
260
+
261
+ rb_define_alloc_func(rb_cMap, &alloc);
262
+ rb_include_module(rb_cMap, rb_mEnumerable);
263
+ rb_define_private_method(rb_cMap, "initialize", __F(&initialize), 0);
264
+ rb_define_method(rb_cMap, "[]", __F(&get), 1);
265
+ rb_define_method(rb_cMap, "[]=", __F(&set), 2);
266
+ rb_define_method(rb_cMap, "each", __F(&each), 0);
267
+ rb_define_method(rb_cMap, "erase", __F(&erase), 1);
268
+ rb_define_method(rb_cMap, "delete", __F(&erase), 1);
269
+ rb_define_method(rb_cMap, "size", __F(&size), 0);
270
+ rb_define_method(rb_cMap, "length", __F(&size), 0);
271
+ rb_define_method(rb_cMap, "empty?", __F(&empty), 0);
272
+ rb_define_method(rb_cMap, "clear", __F(&clear), 0);
273
+ }
274
+ };
275
+
276
+ template <class T>
277
+ struct SparsehashSet {
278
+ T *s;
279
+
280
+ static void mark(SparsehashSet<T> *p) {
281
+ if (!p->s) {
282
+ return;
283
+ }
284
+
285
+ T *s = p->s;
286
+
287
+ for(typename T::iterator i = s->begin(); i != s->end(); i++) {
288
+ rb_gc_mark(*i);
289
+ }
290
+ }
291
+
292
+ static void free(SparsehashSet<T> *p) {
293
+ if (p->s) {
294
+ delete p->s;
295
+ }
296
+
297
+ delete p;
298
+ }
299
+
300
+ static VALUE alloc(VALUE klass) {
301
+ SparsehashSet<T> *p;
302
+
303
+ p = new SparsehashSet<T>;
304
+ p->s = NULL;
305
+
306
+ return Data_Wrap_Struct(klass, &mark, &free, p);
307
+ }
308
+
309
+ static VALUE initialize(VALUE self) {
310
+ SparsehashSet<T> *p;
311
+
312
+ Data_Get_Struct(self, SparsehashSet<T>, p);
313
+ p->s = new T;
314
+ sparsehash_initialize<T>(p->s);
315
+
316
+ return Qnil;
317
+ }
318
+
319
+ static VALUE insert(VALUE self, VALUE value) {
320
+ SparsehashSet<T> *p;
321
+
322
+ sparsehash_validate_key<T>(value);
323
+ Data_Get_Struct(self, SparsehashSet<T>, p);
324
+ T &s = *(p->s);
325
+ s.insert(value);
326
+
327
+ return self;
328
+ }
329
+
330
+ static VALUE each0(VALUE arg) {
331
+ return rb_yield(arg);
332
+ }
333
+
334
+ static VALUE each(VALUE self) {
335
+ SparsehashSet<T> *p;
336
+
337
+ rb_need_block();
338
+
339
+ Data_Get_Struct(self, SparsehashSet<T>, p);
340
+ T &s = *(p->s);
341
+ int status = 0;
342
+
343
+ for(typename T::iterator i = s.begin(); i != s.end(); i++) {
344
+ rb_protect(each0, *i, &status);
345
+
346
+ if (status != 0) {
347
+ break;
348
+ }
349
+ }
350
+
351
+ return self;
352
+ }
353
+
354
+ static VALUE erase(VALUE self, VALUE value) {
355
+ SparsehashSet<T> *p;
356
+
357
+ sparsehash_validate_key<T>(value);
358
+ Data_Get_Struct(self, SparsehashSet<T>, p);
359
+ T &s = *(p->s);
360
+ s.erase(value);
361
+
362
+ return self;
363
+ }
364
+
365
+ static VALUE size(VALUE self) {
366
+ SparsehashSet<T> *p;
367
+
368
+ Data_Get_Struct(self, SparsehashSet<T>, p);
369
+ T &s = *(p->s);
370
+
371
+ return LONG2NUM(s.size());
372
+ }
373
+
374
+ static VALUE empty(VALUE self) {
375
+ SparsehashSet<T> *p;
376
+
377
+ Data_Get_Struct(self, SparsehashSet<T>, p);
378
+ T &s = *(p->s);
379
+
380
+ return s.empty() ? Qtrue : Qfalse;
381
+ }
382
+
383
+ static VALUE clear(VALUE self) {
384
+ SparsehashSet<T> *p;
385
+
386
+ Data_Get_Struct(self, SparsehashSet<T>, p);
387
+ T &s = *(p->s);
388
+ s.clear();
389
+
390
+ return self;
391
+ }
392
+
393
+ static void init(VALUE &module, const char *name) {
394
+ VALUE rb_cSet = rb_define_class_under(module, name, rb_cObject);
395
+
396
+ rb_define_alloc_func(rb_cSet, &alloc);
397
+ rb_include_module(rb_cSet, rb_mEnumerable);
398
+ rb_define_private_method(rb_cSet, "initialize", __F(&initialize), 0);
399
+ rb_define_method(rb_cSet, "insert", __F(&insert), 1);
400
+ rb_define_method(rb_cSet, "<<", __F(&insert), 1);
401
+ rb_define_method(rb_cSet, "each", __F(&each), 0);
402
+ rb_define_method(rb_cSet, "erase", __F(&erase), 1);
403
+ rb_define_method(rb_cSet, "delete", __F(&erase), 1);
404
+ rb_define_method(rb_cSet, "size", __F(&size), 0);
405
+ rb_define_method(rb_cSet, "length", __F(&size), 0);
406
+ rb_define_method(rb_cSet, "empty?", __F(&empty), 0);
407
+ rb_define_method(rb_cSet, "clear", __F(&clear), 0);
408
+ }
409
+ };
410
+
411
+ } // namespace
412
+
413
+ void Init_sparsehash() {
414
+ VALUE rb_mSparsehash = rb_define_module("Sparsehash");
415
+ SparsehashMap<SHMap>::init(rb_mSparsehash, "SparseHashMap");
416
+ SparsehashMap<DHMap>::init(rb_mSparsehash, "DenseHashMap");
417
+ SparsehashSet<SHSet>::init(rb_mSparsehash, "SparseHashSet");
418
+ SparsehashSet<DHSet>::init(rb_mSparsehash, "DenseHashSet");
419
+
420
+ VALUE rb_mSTL = rb_define_module("STL");
421
+ SparsehashMap<STLMap>::init(rb_mSTL, "Map");
422
+ SparsehashSet<STLSet>::init(rb_mSTL, "Set");
423
+
424
+ #ifdef __GNUC__
425
+ VALUE rb_mGNU = rb_define_module("GNU");
426
+ SparsehashMap<GNUHashMap>::init(rb_mGNU, "HashMap");
427
+ SparsehashSet<GNUHashSet>::init(rb_mGNU, "HashSet");
428
+ #endif
429
+ }
@@ -0,0 +1,26 @@
1
+ #ifndef __SPARSEHASH_INTERNAL_H__
2
+ #define __SPARSEHASH_INTERNAL_H__
3
+
4
+ #include "ruby.h"
5
+
6
+ #ifndef RSTRING_PTR
7
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
8
+ #endif
9
+ #ifndef RSTRING_LEN
10
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
11
+ #endif
12
+
13
+ #ifdef _WIN32
14
+ #define __F(f) (reinterpret_cast<VALUE (__cdecl *)(...)>(f))
15
+ #else
16
+ #define __F(f) (reinterpret_cast<VALUE (*)(...)>(f))
17
+ #endif
18
+
19
+ extern "C" {
20
+ #ifdef _WIN32
21
+ __declspec(dllexport)
22
+ #endif
23
+ void Init_sparsehash();
24
+ }
25
+
26
+ #endif // __SPARSEHASH_INTERNAL_H__
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sparsehash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - winebarrel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-20 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: sgwr_dts@yahoo.co.jp
18
+ executables: []
19
+
20
+ extensions:
21
+ - ext/extconf.rb
22
+ extra_rdoc_files:
23
+ - README
24
+ - etc/anymap.rb
25
+ - etc/anyset.rb
26
+ files:
27
+ - ext/extconf.rb
28
+ - ext/sparsehash.cpp
29
+ - ext/sparsehash_internal.h
30
+ - README
31
+ - etc/anymap.rb
32
+ - etc/anyset.rb
33
+ has_rdoc: true
34
+ homepage: http://sparsehash.rubyforge.org
35
+ post_install_message:
36
+ rdoc_options:
37
+ - --title
38
+ - sparsehash - Ruby bindings for Google Sparse Hash.
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project: sparsehash
56
+ rubygems_version: 1.3.1
57
+ signing_key:
58
+ specification_version: 2
59
+ summary: Ruby bindings for Google Sparse Hash.
60
+ test_files: []
61
+