google_hash 0.0.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -2,7 +2,7 @@ This is a ruby gem that wraps google's "sparse" and "dense" hashes.
2
2
 
3
3
  Current usage:
4
4
 
5
- a = GoogleHash.new
5
+ a = GoogleHashSmall.new
6
6
  a[3] = 'abc' # only accept integers for keys currently.
7
7
 
8
8
  The dense hash tends to be a bit faster than ruby's normal hash, and the sparse hash tends to use less RAM.
data/Rakefile CHANGED
@@ -2,10 +2,10 @@ require 'jeweler'
2
2
  Jeweler::Tasks.new do |gemspec|
3
3
  gemspec.name = "google_hash"
4
4
  gemspec.summary = "Ruby wrappers to the google hash library"
5
- gemspec.description = "A different and possibly longer explanation of"
5
+ gemspec.description = gemspec.summary
6
6
  gemspec.email = "rogerdpack@gmail.com"
7
7
  gemspec.homepage = "http://github.com/rdp/ruby_google_hash"
8
8
  gemspec.authors = ["rogerdpack"]
9
- gemspec.add_development_dependency('sane')
9
+ gemspec.add_dependency('sane')
10
10
  end
11
11
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.1.1
@@ -0,0 +1,9 @@
1
+ require './google_hash'
2
+ require 'benchmark'
3
+
4
+ for name in [GoogleHashSparse, GoogleHashDense, Hash, GoogleHash] do
5
+ subject = name.new
6
+ puts name, Benchmark.realtime { 500000.times {|n| subject[n] = 4}}.to_s + " (populate)"
7
+ puts Benchmark.realtime { subject.each{|k, v| }}.to_s + " (each)", ''
8
+
9
+ end
@@ -1,15 +1,33 @@
1
1
  require 'mkmf'
2
+ require 'erb'
2
3
  require 'rubygems'
3
4
  require 'sane'
4
5
 
5
6
  # build google's lib locally...
7
+
6
8
  dir = Dir.pwd
7
9
  Dir.chdir 'sparsehash-1.5.2' do
8
10
  dir = dir + '/local_installed'
9
11
  command = "sh configure --prefix=#{dir} && make && make install"
10
12
  puts command
11
- system command
13
+ # only if necessary
14
+ system command unless File.directory?(dir)
12
15
  end
13
16
 
14
17
  $CFLAGS += " -I./local_installed/include "
18
+
19
+ if RUBY_VERSION < '1.9'
20
+ # appears to link using gcc on 1.8 [mingw at least]
21
+ $LDFLAGS += " -lstdc++ "
22
+ end
23
+
24
+ # create our files...
25
+ # currently we're int only...hmm...
26
+ # ltodo 64 bit compat...
27
+
28
+ for type, setup_code in {'sparse' => nil, 'dense' => 'set_empty_key(1<<31);' } do
29
+ template = ERB.new(File.read('template/go.cpp'))
30
+ File.write(type.to_s + '.cpp', template.result(binding))
31
+ end
32
+
15
33
  create_makefile('google_hash')
@@ -0,0 +1 @@
1
+ ruby extconf.rb && make clean && make && ruby benchmark.rb
@@ -0,0 +1,12 @@
1
+ extern "C" {
2
+ #include <ruby.h>
3
+ extern void init_dense();
4
+ extern void init_sparse();
5
+
6
+ void Init_google_hash() {
7
+ init_dense();
8
+ init_sparse();
9
+ rb_eval_string("GoogleHash = GoogleHashDense");
10
+ }
11
+ }
12
+
@@ -0,0 +1,114 @@
1
+ #include <iostream>
2
+ #include <google/<%= type %>_hash_map>
3
+ #include <ruby.h>
4
+
5
+ using google::<%= type %>_hash_map; // namespace where class lives by default
6
+ using std::cout;
7
+ using std::endl;
8
+ <% if !OS.windows? %>
9
+ #include <ext/hash_set>
10
+ <% end %>
11
+ using __gnu_cxx::hash; // or __gnu_cxx::hash, or maybe tr1::hash, depending on your OS
12
+ extern "C" {
13
+
14
+ struct eqstr
15
+ {
16
+ bool operator()(const char* s1, const char* s2) const
17
+ {
18
+ return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
19
+ }
20
+ };
21
+
22
+
23
+ struct eqint
24
+ {
25
+ inline bool operator()(int s1, int s2) const
26
+ {
27
+ return s1 == s2;
28
+ }
29
+ };
30
+
31
+ typedef struct {
32
+ <%= type %>_hash_map<int, VALUE> *hash_map;
33
+ } RCallback;
34
+
35
+ static VALUE rb_cGoogleHash<%= type %>;
36
+
37
+
38
+ static void mark_hash_map_values(RCallback *incoming) {
39
+ for(<%= type %>_hash_map<int, VALUE>::iterator it = incoming->hash_map->begin(); it != incoming->hash_map->end(); ++it) {
40
+ rb_gc_mark(it->second);
41
+ }
42
+ }
43
+
44
+ static void free_hash_callback(RCallback* cb) {
45
+ // delete cb->hash_map;
46
+ }
47
+
48
+ static VALUE callback_alloc _((VALUE)); // what does this line do?
49
+
50
+ static VALUE
51
+ callback_alloc( VALUE klass )
52
+ {
53
+ VALUE cb;
54
+ RCallback* cbs;
55
+ cb = Data_Make_Struct(klass, RCallback, mark_hash_map_values, free_hash_callback, cbs);
56
+ cbs->hash_map = new <%= type %>_hash_map<int, VALUE>();
57
+ <% if setup_code %>
58
+ cbs->hash_map-><%= setup_code %>;
59
+ <% end %>
60
+ return cb;
61
+ }
62
+
63
+ #define GetCallbackStruct(obj) (Check_Type(obj, T_DATA), (RCallback*)DATA_PTR(obj))
64
+
65
+ static VALUE
66
+ rb_mri_hash_new(VALUE freshly_created) {
67
+
68
+ // we don't actually have anything special to do here...
69
+ return freshly_created;
70
+ }
71
+
72
+
73
+ static VALUE rb_ghash_set(VALUE cb, VALUE set_this, VALUE to_this) {
74
+ if(!(TYPE(set_this) == T_FIXNUM)) {
75
+ rb_raise(rb_eTypeError, "not valid value");
76
+ }
77
+ RCallback* cbs = GetCallbackStruct(cb);
78
+ (*cbs->hash_map)[FIX2INT(set_this)] = to_this;
79
+ return to_this; // ltodo test that it returns value...
80
+ }
81
+
82
+ static VALUE rb_ghash_get(VALUE cb, VALUE get_this) {
83
+ if(!(TYPE(get_this) == T_FIXNUM)) {
84
+ rb_raise(rb_eTypeError, "not valid value");
85
+ }
86
+ RCallback* cbs = GetCallbackStruct(cb);
87
+ VALUE out = (*cbs->hash_map)[FIX2INT(get_this)];
88
+ // todo if out == 0 return Qnil
89
+ return out;
90
+ }
91
+
92
+ static VALUE rb_ghash_each(VALUE cb) {
93
+ RCallback* incoming = GetCallbackStruct(cb);
94
+ // TODO assert block given
95
+ for(<%= type %>_hash_map<int, VALUE>::iterator it = incoming->hash_map->begin(); it != incoming->hash_map->end(); ++it) {
96
+ rb_yield_values(2, INT2FIX(it->first), it->second);
97
+ }
98
+ return cb;
99
+
100
+ }
101
+
102
+ void init_<%= type %>() {
103
+ rb_cGoogleHash<%= type %> = rb_define_class("GoogleHash<%= type.capitalize %>", rb_cObject);
104
+
105
+ rb_define_alloc_func(rb_cGoogleHash<%= type %>, callback_alloc); // I guess it calls this for us, pre initialize...
106
+
107
+ rb_define_method(rb_cGoogleHash<%= type %>, "initialize", RUBY_METHOD_FUNC(rb_mri_hash_new), 0);
108
+ rb_define_method(rb_cGoogleHash<%= type %>, "[]=", RUBY_METHOD_FUNC(rb_ghash_set), 2);
109
+ rb_define_method(rb_cGoogleHash<%= type %>, "[]", RUBY_METHOD_FUNC(rb_ghash_get), 1);
110
+ rb_define_method(rb_cGoogleHash<%= type %>, "each", RUBY_METHOD_FUNC(rb_ghash_each), 0);
111
+
112
+ }
113
+ }
114
+
@@ -0,0 +1,57 @@
1
+ 1.9 mingw:
2
+
3
+ GoogleHashSparse
4
+ 0.53125 (populate)
5
+ 0.078125 (each)
6
+
7
+ GoogleHashDense
8
+ 0.1875 (populate)
9
+ 0.078125 (each)
10
+
11
+ Hash
12
+ 0.359375 (populate)
13
+ 1.1875 (each)
14
+
15
+
16
+ ruby 1.8.6 mingw:
17
+
18
+ GoogleHashSparse
19
+ 0.625 (populate)
20
+ 0.546875(each)
21
+
22
+ GoogleHashDense
23
+ 0.234375(populate)
24
+ 0.421875(each)
25
+
26
+ Hash
27
+ 0.5 (populate)
28
+ 0.53125 (each)
29
+
30
+
31
+ 1.9.2 linux:
32
+
33
+ GoogleHashSparse
34
+ 0.3342118263244629 (populate)
35
+ 0.05078697204589844 (each)
36
+
37
+ GoogleHashDense
38
+ 0.14588713645935059 (populate)
39
+ 0.056185007095336914 (each)
40
+
41
+ Hash
42
+ 0.34199094772338867 (populate)
43
+ 0.8924679756164551 (each)
44
+
45
+ 1.8.6 linux:
46
+
47
+ GoogleHashSparse
48
+ 0.305501222610474 (populate)
49
+ 0.78859806060791 (each)
50
+
51
+ GoogleHashDense
52
+ 0.161197900772095 (populate)
53
+ 0.810173988342285 (each)
54
+
55
+ Hash
56
+ 0.269010782241821 (populate)
57
+ 1.00644612312317 (each)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google_hash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - rogerdpack
@@ -9,12 +9,12 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-15 00:00:00 -07:00
12
+ date: 2009-12-15 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sane
17
- type: :development
17
+ type: :runtime
18
18
  version_requirement:
19
19
  version_requirements: !ruby/object:Gem::Requirement
20
20
  requirements:
@@ -22,7 +22,7 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: "0"
24
24
  version:
25
- description: A different and possibly longer explanation of
25
+ description: Ruby wrappers to the google hash library
26
26
  email: rogerdpack@gmail.com
27
27
  executables: []
28
28
 
@@ -34,8 +34,10 @@ files:
34
34
  - README
35
35
  - Rakefile
36
36
  - VERSION
37
+ - ext/benchmark.rb
37
38
  - ext/extconf.rb
38
- - ext/go.cpp
39
+ - ext/go.bat
40
+ - ext/main.cpp
39
41
  - ext/sparsehash-1.5.2/AUTHORS
40
42
  - ext/sparsehash-1.5.2/COPYING
41
43
  - ext/sparsehash-1.5.2/ChangeLog
@@ -113,7 +115,8 @@ files:
113
115
  - ext/sparsehash-1.5.2/vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj
114
116
  - ext/sparsehash-1.5.2/vsprojects/time_hash_map/time_hash_map.vcproj
115
117
  - ext/sparsehash-1.5.2/vsprojects/type_traits_unittest/type_traits_unittest.vcproj
116
- - ext/test.rb
118
+ - ext/template/go.cpp
119
+ - results.txt
117
120
  - test/spec.go
118
121
  has_rdoc: true
119
122
  homepage: http://github.com/rdp/ruby_google_hash
data/ext/go.cpp DELETED
@@ -1,109 +0,0 @@
1
- #include <iostream>
2
- #include <google/sparse_hash_map>
3
- #include <ruby.h>
4
-
5
- using google::sparse_hash_map; // namespace where class lives by default
6
- using std::cout;
7
- using std::endl;
8
- using __gnu_cxx::hash; // or __gnu_cxx::hash, or maybe tr1::hash, depending on your OS
9
- extern "C" {
10
-
11
- struct eqstr
12
- {
13
- bool operator()(const char* s1, const char* s2) const
14
- {
15
- return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
16
- }
17
- };
18
-
19
-
20
- struct eqint
21
- {
22
- inline bool operator()(int s1, int s2) const
23
- {
24
- return s1 == s2;
25
- }
26
- };
27
-
28
- typedef struct {
29
- sparse_hash_map<int, VALUE> *hash_map;
30
- } RCallback;
31
-
32
- static VALUE rb_cGoogleHashSmall;
33
-
34
-
35
- static void mark_hash_map_values(RCallback incoming) {} // TODO, etc.
36
-
37
- static VALUE callback_alloc _((VALUE)); // what does this line do?
38
-
39
- static VALUE
40
- callback_alloc( VALUE klass )
41
- {
42
- VALUE cb;
43
- RCallback* cbs;
44
- cb = Data_Make_Struct(klass, RCallback, /*mark_mri_callback*/ 0, 0 /*free_mri_callback*/, cbs);
45
- cbs->hash_map = new sparse_hash_map<int, VALUE>();
46
- sparse_hash_map<int, int> a;
47
- a[35] = 47;
48
- sparse_hash_map<int, int> *a2 = new sparse_hash_map<int, int>;
49
- (*a2)[35] = 37;
50
- (*cbs->hash_map)[33] = 35;
51
- return cb;
52
- }
53
-
54
- #define GetCallbackStruct(obj) (Check_Type(obj, T_DATA), (RCallback*)DATA_PTR(obj))
55
-
56
- static VALUE
57
- rb_mri_hash_new(VALUE freshly_created) {
58
-
59
- // we don't actually have anything special to do here...
60
- return freshly_created;
61
- }
62
-
63
- int main()
64
- {
65
- sparse_hash_map<const char*, int, hash<const char*>, eqstr> months;
66
-
67
- months["april"] = 30;
68
-
69
- cout << "april -> " << months["april"] << endl;
70
- cout << "iterating";
71
- for(sparse_hash_map<const char*, int, hash<const char*>, eqstr>::iterator it = months.begin(); it != months.end(); ++it) {
72
- cout << it->first;
73
- }
74
-
75
- }
76
- static VALUE rb_ghash_set(VALUE cb, VALUE set_this, VALUE to_this) {
77
- if(!(TYPE(set_this) == T_FIXNUM)) {
78
- rb_raise(rb_eTypeError, "not valid value");
79
- }
80
- RCallback* cbs = GetCallbackStruct(cb);
81
- (*cbs->hash_map)[FIX2INT(set_this)] = to_this;
82
- return to_this; // ltodo test that it returns value...
83
- }
84
-
85
- static VALUE rb_ghash_get(VALUE cb, VALUE get_this) {
86
- if(!(TYPE(get_this) == T_FIXNUM)) {
87
- rb_raise(rb_eTypeError, "not valid value");
88
- }
89
- RCallback* cbs = GetCallbackStruct(cb);
90
- VALUE out = (*cbs->hash_map)[FIX2INT(get_this)];
91
- // todo if out == 0 return Qnil
92
- return out;
93
- }
94
-
95
- void Init_google_hash() {
96
- rb_cGoogleHashSmall = rb_define_class("GoogleHashSmall", rb_cObject);
97
-
98
- rb_define_alloc_func(rb_cGoogleHashSmall, callback_alloc); // I guess it calls this for us, pre initialize...
99
-
100
- rb_define_method(rb_cGoogleHashSmall, "initialize", RUBY_METHOD_FUNC(rb_mri_hash_new), 0);
101
- rb_define_method(rb_cGoogleHashSmall, "[]=", RUBY_METHOD_FUNC(rb_ghash_set), 2);
102
- rb_define_method(rb_cGoogleHashSmall, "[]", RUBY_METHOD_FUNC(rb_ghash_get), 1);
103
-
104
-
105
- main();
106
-
107
- }
108
- }
109
-
@@ -1,10 +0,0 @@
1
- require 'google_hash'
2
- a = GoogleHashSmall.new
3
- puts
4
- a[3] = 4
5
-
6
- require 'benchmark'
7
- b = {}
8
- puts Benchmark.realtime { 1000.times { 1000.times {|n| b[n] = 4}}}
9
- puts Benchmark.realtime { 1000.times { 1000.times {|n| a[n] = 4}}}
10
-