sparsehash 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+