native_btree 0.1.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4350c3868f788f61a124316be8b5585fdaeff625d68146132400dc35d8c11c65
4
+ data.tar.gz: 6d8d0ab48fd80fe1495fc467e94aab3697f3a6f268b3922c192de766d5ce97ca
5
+ SHA512:
6
+ metadata.gz: e75a27871d722cd11d5453d980ef55698cc9de9c25fc1dd825a0e824189171f6ebb827def85616659ff778ad30739df84579bc02b9639f2c64cd1803ee301d57
7
+ data.tar.gz: cfab277fb1f5c2265a94f588aaf27a1002c210fb1c70aea5d6311e1b5f39de9f356e5b0b89c9ff0f5ab8441ca9731576b824bfe975a719b0ef60403ece9f2545
@@ -0,0 +1,128 @@
1
+ #include "btree.h"
2
+
3
+ BTree::BTree(VALUE comnparator)
4
+ {
5
+ this->comparator = comnparator;
6
+ this->tree = g_tree_new_with_data(BTree::nativeComparator, this);
7
+ }
8
+
9
+ BTree::~BTree()
10
+ {
11
+ g_tree_destroy(this->tree);
12
+ }
13
+
14
+ void
15
+ BTree::mark()
16
+ {
17
+ rb_gc_mark(this->comparator);
18
+ this->markMyRValues();
19
+ }
20
+
21
+ void
22
+ BTree::markMyRValues()
23
+ {
24
+ g_tree_foreach(this->tree, BTree::markRValue, NULL);
25
+ }
26
+
27
+ gint
28
+ BTree::markRValue(gpointer k, gpointer v, gpointer not_used)
29
+ {
30
+ const VALUE key = reinterpret_cast<VALUE>(k);
31
+ const VALUE value = reinterpret_cast<VALUE>(v);
32
+
33
+ rb_gc_mark(key);
34
+ rb_gc_mark(value);
35
+
36
+ return false;
37
+ }
38
+
39
+ gint
40
+ BTree::nativeComparator(gconstpointer a, gconstpointer b, gpointer data)
41
+ {
42
+ const BTree *tree = static_cast<BTree *>(data);
43
+ const VALUE keyA = reinterpret_cast<VALUE>(a);
44
+ const VALUE keyB = reinterpret_cast<VALUE>(b);
45
+
46
+ VALUE ruby_result = rb_funcall(tree->comparator, rb_intern("call"), 2, keyA, keyB);
47
+
48
+ return NUM2INT(ruby_result);
49
+ }
50
+
51
+ gint
52
+ BTree::size()
53
+ {
54
+ return g_tree_nnodes(this->tree);
55
+ }
56
+
57
+ gint
58
+ BTree::height()
59
+ {
60
+ return g_tree_height(this->tree);
61
+ }
62
+
63
+ void
64
+ BTree::set(VALUE key, VALUE value)
65
+ {
66
+ g_tree_replace(this->tree, (gpointer) key, (gpointer) value);
67
+ }
68
+
69
+ VALUE
70
+ BTree::get(VALUE key)
71
+ {
72
+ gpointer result = g_tree_lookup(this->tree, reinterpret_cast<gconstpointer>(key));
73
+
74
+ if (!result) {
75
+ return Qnil;
76
+ }
77
+
78
+ return reinterpret_cast<VALUE>(result);
79
+ }
80
+
81
+ bool
82
+ BTree::del(VALUE key)
83
+ {
84
+ return g_tree_remove(this->tree, reinterpret_cast<gconstpointer>(key));
85
+ }
86
+
87
+ void
88
+ BTree::clear()
89
+ {
90
+ g_tree_unref(this->tree);
91
+ this->tree = g_tree_new_with_data(BTree::nativeComparator, this);
92
+ }
93
+
94
+ bool
95
+ BTree::has(VALUE key)
96
+ {
97
+ bool result = g_tree_lookup(this->tree, reinterpret_cast<gconstpointer>(key));
98
+
99
+ if (!result) {
100
+ return true;
101
+ }
102
+
103
+ return false;
104
+ }
105
+
106
+ gboolean
107
+ BTree::traverseFunc(gpointer k, gpointer v, gpointer b)
108
+ {
109
+ const VALUE key = reinterpret_cast<VALUE>(k);
110
+ const VALUE value = reinterpret_cast<VALUE>(v);
111
+ const VALUE block = reinterpret_cast<VALUE>(b);
112
+
113
+ rb_funcall(block, rb_intern("call"), 2, key, value);
114
+
115
+ return FALSE;
116
+ }
117
+
118
+ void
119
+ BTree::each(VALUE block)
120
+ {
121
+ g_tree_foreach(this->tree, BTree::traverseFunc, reinterpret_cast<gpointer>(block));
122
+ }
123
+
124
+ void
125
+ BTree::each(GTraverseFunc func, gpointer data)
126
+ {
127
+ g_tree_foreach(this->tree, func, data);
128
+ }
@@ -0,0 +1,11 @@
1
+ #ifndef EXTCONF_H
2
+ #define EXTCONF_H
3
+ #define HAVE_G_TREE_INSERT 1
4
+ #define HAVE_G_TREE_REPLACE 1
5
+ #define HAVE_G_TREE_NNODES 1
6
+ #define HAVE_G_TREE_LOOKUP 1
7
+ #define HAVE_G_TREE_FOREACH 1
8
+ #define HAVE_G_TREE_SEARCH 1
9
+ #define HAVE_G_TREE_DESTROY 1
10
+ #define HAVE_G_TREE_HEIGHT 1
11
+ #endif
@@ -0,0 +1,35 @@
1
+ require "mkmf"
2
+
3
+ local_include = %w(
4
+ $(srcdir)/include
5
+ );
6
+
7
+ ldflags = cppflags = nil
8
+
9
+ pkg_config "glib-2.0"
10
+ dir_config 'glib', cppflags, ldflags
11
+
12
+ abort "Can't find the glib.h header" unless find_header 'glib.h'
13
+ abort "Can't find the glib libary'" unless find_library 'glib-2.0', 'g_tree_new_full'
14
+ abort "g_tree_insert() not found" unless have_func 'g_tree_insert'
15
+ abort "g_tree_replace() not found" unless have_func 'g_tree_replace'
16
+ abort "g_tree_nnodes() not found" unless have_func 'g_tree_nnodes'
17
+ abort "g_tree_lookup() not found" unless have_func 'g_tree_lookup'
18
+ abort "g_tree_foreach() not found" unless have_func 'g_tree_foreach'
19
+ abort "g_tree_search() not found" unless have_func 'g_tree_search'
20
+ abort "g_tree_destroy() not found" unless have_func 'g_tree_destroy'
21
+ abort "g_tree_height() not found" unless have_func 'g_tree_height'
22
+
23
+ $DEBUG = true
24
+
25
+ $VPATH.concat %w(
26
+ $(srcdir)/include
27
+ )
28
+
29
+ $INCFLAGS << local_include.map{|dir| " -I#{dir}" }.join("")
30
+ CONFIG["debugflags"] = "-ggdb3"
31
+ CONFIG["optflags"] = "-O0"
32
+ $CXXFLAGS = "-O0 -ggdb3 -pipe"
33
+
34
+ create_header
35
+ create_makefile "native_btree/native_btree"
@@ -0,0 +1,63 @@
1
+ #include <string>
2
+ #include <ruby.h>
3
+ #include <glib.h>
4
+
5
+ using namespace std;
6
+
7
+ class BTree {
8
+ public:
9
+ BTree(VALUE comparator);
10
+ ~BTree();
11
+
12
+ // get
13
+ VALUE const &operator[](VALUE key) const;
14
+ // set
15
+ void operator[](VALUE key);
16
+
17
+ gint
18
+ height();
19
+
20
+ gint
21
+ size();
22
+
23
+ bool
24
+ del(VALUE key);
25
+
26
+ void
27
+ clear();
28
+
29
+ bool
30
+ has(VALUE key);
31
+
32
+ void
33
+ mark();
34
+
35
+ void
36
+ set(VALUE key, VALUE value);
37
+
38
+ VALUE
39
+ get(VALUE key);
40
+
41
+ void
42
+ each(VALUE block);
43
+
44
+ void
45
+ each(GTraverseFunc func, gpointer data);
46
+
47
+ private:
48
+ GTree *tree;
49
+ VALUE comparator;
50
+
51
+ void
52
+ markMyRValues();
53
+
54
+ static gint
55
+ nativeComparator(gconstpointer keyA, gconstpointer keyB, gpointer tree);
56
+
57
+ static gint
58
+ markRValue(gpointer key, gpointer value, gpointer not_used);
59
+
60
+ static gboolean
61
+ traverseFunc(gpointer k, gpointer v, gpointer data);
62
+ };
63
+
@@ -0,0 +1,51 @@
1
+ #ifndef _NATIVE_BTREE_
2
+ #include <ruby.h>
3
+
4
+ #if defined(__cplusplus)
5
+ extern "C" {
6
+ #endif
7
+
8
+ extern VALUE btree_class;
9
+ extern VALUE btree_module;
10
+
11
+ VALUE
12
+ btree_new(VALUE klass);
13
+
14
+ VALUE
15
+ btree_init(VALUE self);
16
+
17
+ VALUE
18
+ btree_size(VALUE self);
19
+
20
+ VALUE
21
+ btree_height(VALUE self);
22
+
23
+ VALUE
24
+ btree_set(VALUE self, VALUE key, VALUE value);
25
+
26
+ VALUE
27
+ btree_get(VALUE self, VALUE key);
28
+
29
+ VALUE
30
+ btree_delete(VALUE self, VALUE key);
31
+
32
+ VALUE
33
+ btree_clear(VALUE self);
34
+
35
+ VALUE
36
+ btree_has(VALUE self, VALUE key);
37
+
38
+ VALUE
39
+ btree_each(VALUE self);
40
+
41
+ VALUE
42
+ btree_cmp(VALUE self, VALUE tree2);
43
+
44
+ VALUE
45
+ btree_equal(VALUE self, VALUE tree2);
46
+
47
+ #if defined(__cplusplus)
48
+ }
49
+ #endif
50
+
51
+ #endif // _NATIVE_BTREE_
@@ -0,0 +1,30 @@
1
+ #include <native_btree.h>
2
+
3
+ VALUE btree_class;
4
+ VALUE btree_module;
5
+
6
+ void
7
+ Init_native_btree()
8
+ {
9
+ btree_module = rb_define_module("NativeBTree");
10
+ btree_class = rb_define_class_under(btree_module, "BTree", rb_cObject);
11
+
12
+ rb_define_singleton_method(btree_class, "new", btree_new, 0);
13
+ // rb_define_method(btree_class, "initialize", btree_init, 0);
14
+ rb_define_method(btree_class, "size", btree_size, 0);
15
+ rb_define_method(btree_class, "height", btree_height, 0);
16
+ rb_define_method(btree_class, "set", btree_set, 2);
17
+ rb_define_alias(btree_class, "[]=", "set");
18
+ rb_define_method(btree_class, "get", btree_get, 1);
19
+ rb_define_alias(btree_class, "[]", "get");
20
+ rb_define_method(btree_class, "delete", btree_delete, 1);
21
+ rb_define_method(btree_class, "clear", btree_clear, 0);
22
+ rb_define_method(btree_class, "has", btree_has, 1);
23
+ rb_define_method(btree_class, "each", btree_each, 0);
24
+ rb_define_method(btree_class, "<=>", btree_cmp, 1);
25
+ rb_define_method(btree_class, "eql?", btree_equal, 1);
26
+ rb_define_alias(btree_class, "==", "eql?");
27
+ // TODO: to_ary
28
+ // TODO: to_hash
29
+ }
30
+
@@ -0,0 +1,221 @@
1
+ #include <ruby.h>
2
+ #include <glib.h>
3
+
4
+ #include "native_btree.h"
5
+ #include "btree.h"
6
+
7
+
8
+ extern "C" {
9
+
10
+ class BTreeEQCtxt {
11
+ public:
12
+ VALUE eq = Qtrue;
13
+ BTree *tree2 = nullptr;
14
+ };
15
+
16
+ static void
17
+ btree_free(BTree *btree)
18
+ {
19
+ delete btree;
20
+ }
21
+
22
+ static void
23
+ btree_mark(gpointer obj)
24
+ {
25
+ reinterpret_cast<BTree *>(obj)->mark();
26
+ }
27
+
28
+ static VALUE
29
+ btree_enum_size(VALUE tree, VALUE args, VALUE eobj)
30
+ {
31
+ return btree_size(tree);
32
+ }
33
+
34
+
35
+ VALUE
36
+ btree_new(VALUE klass)
37
+ {
38
+ rb_need_block();
39
+
40
+ VALUE comparator = rb_block_lambda();
41
+
42
+ BTree *tree = new BTree(comparator);
43
+
44
+ VALUE instance = Data_Wrap_Struct(klass, btree_mark, btree_free, tree);
45
+
46
+ return instance;
47
+ }
48
+
49
+ VALUE
50
+ btree_init(VALUE self)
51
+ {
52
+ return self;
53
+ }
54
+
55
+ VALUE
56
+ btree_size(VALUE self)
57
+ {
58
+ BTree *tree;
59
+ Data_Get_Struct(self, BTree, tree);
60
+
61
+ VALUE result = INT2NUM(tree->size());
62
+
63
+ return result;
64
+ }
65
+
66
+ VALUE
67
+ btree_height(VALUE self)
68
+ {
69
+ BTree *tree;
70
+ Data_Get_Struct(self, BTree, tree);
71
+
72
+ VALUE result = INT2NUM(tree->height());
73
+
74
+ return result;
75
+ }
76
+
77
+
78
+ VALUE
79
+ btree_set(VALUE self, VALUE key, VALUE value)
80
+ {
81
+ BTree *tree;
82
+ Data_Get_Struct(self, BTree, tree);
83
+
84
+ tree->set(key, value);
85
+
86
+ return Qnil;
87
+ }
88
+
89
+ VALUE
90
+ btree_get(VALUE self, VALUE key)
91
+ {
92
+ BTree *tree;
93
+ Data_Get_Struct(self, BTree, tree);
94
+
95
+ return tree->get(key);
96
+ }
97
+
98
+ VALUE
99
+ btree_delete(VALUE self, VALUE key)
100
+ {
101
+ BTree *tree;
102
+ Data_Get_Struct(self, BTree, tree);
103
+
104
+ bool result = tree->del(key);
105
+
106
+ return result ? Qtrue : Qfalse;
107
+ }
108
+
109
+ VALUE
110
+ btree_clear(VALUE self)
111
+ {
112
+ BTree *tree;
113
+ Data_Get_Struct(self, BTree, tree);
114
+
115
+ tree->clear();
116
+
117
+ return Qnil;
118
+ }
119
+
120
+ VALUE
121
+ btree_has(VALUE self, VALUE key)
122
+ {
123
+ BTree *tree;
124
+ Data_Get_Struct(self, BTree, tree);
125
+
126
+ bool result = tree->has(key);
127
+
128
+ return result ? Qtrue : Qfalse;
129
+ }
130
+
131
+ VALUE
132
+ btree_each(VALUE self)
133
+ {
134
+ RETURN_SIZED_ENUMERATOR(self, 0, 0, btree_enum_size);
135
+
136
+ VALUE block = rb_block_lambda();
137
+
138
+ BTree *tree;
139
+ Data_Get_Struct(self, BTree, tree);
140
+
141
+ tree->each(block);
142
+
143
+ return Qnil;
144
+ }
145
+
146
+ // TODO: Need implementation
147
+ VALUE
148
+ btree_cmp(VALUE self, VALUE tree2)
149
+ {
150
+ return Qnil;
151
+ }
152
+
153
+ static gboolean
154
+ eql_comparator(gpointer k, gpointer v, gpointer data)
155
+ {
156
+ VALUE key = reinterpret_cast<VALUE>(k);
157
+ VALUE val = reinterpret_cast<VALUE>(v);
158
+ BTreeEQCtxt *context = reinterpret_cast<BTreeEQCtxt *>(data);
159
+
160
+ VALUE val2 = context->tree2->get(key);
161
+
162
+ // key not found
163
+ if (NIL_P(val2)) {
164
+ context->eq = Qfalse;
165
+
166
+ return TRUE;
167
+ }
168
+
169
+ // values !eql
170
+ if (!rb_eql(val, val2)) {
171
+ context->eq = Qfalse;
172
+
173
+ return TRUE;
174
+ }
175
+
176
+ return FALSE;
177
+ }
178
+
179
+ static VALUE// obj arg recur
180
+ recursive_eql(VALUE tree, VALUE tree2, int recur)
181
+ {
182
+ if (recur)
183
+ return Qtrue; /* Subtle! */
184
+
185
+ BTree *t, *t2;
186
+ Data_Get_Struct(tree, BTree, t);
187
+ Data_Get_Struct(tree2, BTree, t2);
188
+
189
+ BTreeEQCtxt context;
190
+ // context.eq == Qtrue;
191
+
192
+ context.tree2 = t2;
193
+
194
+ t->each(eql_comparator, reinterpret_cast<gpointer>(&context));
195
+
196
+ return context.eq;
197
+ }
198
+
199
+ VALUE
200
+ btree_equal(VALUE self, VALUE tree2)
201
+ {
202
+ BTree *t, *t2;
203
+ Data_Get_Struct(self, BTree, t);
204
+ Data_Get_Struct(tree2, BTree, t2);
205
+
206
+ if (self == tree2)
207
+ return Qtrue;
208
+
209
+ if (CLASS_OF(tree2) != btree_class)
210
+ return Qfalse;
211
+
212
+ if (t->size() != t2->size() || t->height() != t2->height())
213
+ return Qfalse;
214
+
215
+ if (t->size() == 0)
216
+ return Qtrue;
217
+ // func obj paired arg
218
+ return rb_exec_recursive_paired(recursive_eql, self, tree2, tree2);
219
+ }
220
+
221
+ }
@@ -0,0 +1,5 @@
1
+ module NativeBTree
2
+ end
3
+
4
+ require "native_btree/version"
5
+ require "native_btree/native_btree"
@@ -0,0 +1,3 @@
1
+ module NativeBTree
2
+ VERSION = "0.1.0.alpha1".freeze
3
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: native_btree
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.alpha1
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Feodorov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-07-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - webmaster@unixcomp.org
16
+ executables: []
17
+ extensions:
18
+ - ext/native_btree/extconf.rb
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ext/native_btree/btree.cc
22
+ - ext/native_btree/extconf.h
23
+ - ext/native_btree/extconf.rb
24
+ - ext/native_btree/include/btree.h
25
+ - ext/native_btree/include/native_btree.h
26
+ - ext/native_btree/native_btree.c
27
+ - ext/native_btree/rb_methods.cc
28
+ - lib/native_btree.rb
29
+ - lib/native_btree/version.rb
30
+ homepage: https://github.com/unixs/ruby-native-btree
31
+ licenses:
32
+ - MIT
33
+ metadata: {}
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '2.5'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.1
48
+ requirements: []
49
+ rubygems_version: 3.1.4
50
+ signing_key:
51
+ specification_version: 4
52
+ summary: Bindings to GTree data stucture from libglib-2.0
53
+ test_files: []