native_btree 0.1.0.alpha1

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.
@@ -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: []