birch 0.0.4-java

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,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile('birch/native')
@@ -0,0 +1,424 @@
1
+ #include <ruby.h>
2
+
3
+ static VALUE birch;
4
+ static VALUE birch_tree;
5
+ static VALUE birch_edge;
6
+
7
+ /*
8
+ * Initialize the node with its value and id.
9
+ * Setup containers for the children, features
10
+ * and dependencies of this node.
11
+ */
12
+ static VALUE birch_initialize(VALUE self, VALUE value, VALUE id)
13
+ {
14
+ VALUE parent;
15
+ VALUE children;
16
+ VALUE children_hash;
17
+ VALUE features;
18
+ VALUE edges;
19
+
20
+ parent = Qnil;
21
+ children = rb_ary_new();
22
+ children_hash = rb_hash_new();
23
+ features = rb_hash_new();
24
+ edges = rb_ary_new();
25
+
26
+ rb_iv_set(self, "@value", value);
27
+ rb_iv_set(self, "@id", id);
28
+ rb_iv_set(self, "@parent", parent);
29
+ rb_iv_set(self, "@children", children);
30
+ rb_iv_set(self, "@children_hash", children_hash);
31
+ rb_iv_set(self, "@features", features);
32
+ rb_iv_set(self, "@edges", edges);
33
+
34
+ return self;
35
+ }
36
+
37
+ static VALUE birch_edge_initialize(int argc, VALUE* argv, VALUE self) {
38
+
39
+ VALUE node_a;
40
+ VALUE node_b;
41
+ VALUE directed;
42
+ VALUE direction;
43
+
44
+ if (argc < 3 || argc > 4) {
45
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
46
+ }
47
+
48
+ rb_iv_set(self, "@node_a", argv[0]);
49
+ rb_iv_set(self, "@node_b", argv[1]);
50
+ rb_iv_set(self, "@directed", argv[2]);
51
+
52
+ if (argc == 4) {
53
+ rb_iv_set(self, "@direction", argv[3]);
54
+ } else {
55
+ rb_iv_set(self, "@direction", Qnil);
56
+ }
57
+
58
+ }
59
+
60
+ /* Return the root of the tree. */
61
+ static VALUE birch_root(VALUE self) {
62
+
63
+ VALUE ancestor;
64
+ VALUE parent;
65
+ VALUE tmp;
66
+
67
+ parent = rb_iv_get(self, "@parent");
68
+
69
+ if (parent == Qnil) {
70
+ return self;
71
+ } else {
72
+ ancestor = parent;
73
+ while (ancestor != Qnil) {
74
+ tmp = rb_iv_get(ancestor, "@parent");
75
+ if (tmp == Qnil) {
76
+ return ancestor;
77
+ } else {
78
+ ancestor = tmp;
79
+ }
80
+ }
81
+ return Qnil;
82
+ }
83
+ }
84
+
85
+ /* Add a child(ren) to this node. Return first child added. */
86
+ static VALUE birch_add(VALUE self, VALUE node_or_nodes) {
87
+
88
+ long i;
89
+ VALUE nodes;
90
+ VALUE child;
91
+ VALUE children;
92
+ VALUE children_hash;
93
+ VALUE child_id;
94
+
95
+ children = rb_iv_get(self, "@children");
96
+ children_hash = rb_iv_get(self, "@children_hash");
97
+
98
+ if (CLASS_OF(node_or_nodes) != rb_cArray) {
99
+ nodes = rb_ary_new();
100
+ rb_funcall(nodes, rb_intern("push"), 1, node_or_nodes);
101
+ } else {
102
+ nodes = node_or_nodes;
103
+ }
104
+
105
+ for (i = 0; i < RARRAY_LEN(nodes); i++) {
106
+
107
+ child = RARRAY_PTR(nodes)[i];
108
+ child_id = rb_iv_get(child, "@id");
109
+
110
+ rb_funcall(children, rb_intern("push"), 1, child);
111
+
112
+ rb_funcall(children_hash, rb_intern("store"),
113
+ 2, child_id, child
114
+ );
115
+ rb_iv_set(child, "@parent", self);
116
+ }
117
+
118
+ return RARRAY_PTR(nodes)[0];
119
+
120
+ }
121
+
122
+ /* Return the feature with the supplied name. */
123
+ static VALUE birch_get(VALUE self, VALUE feature) {
124
+ if (rb_intern("id") == SYM2ID(feature)) {
125
+ return rb_iv_get(self, "@id");
126
+ } else if (SYM2ID(feature) == rb_intern("value")) {
127
+ return rb_iv_get(self, "@value");
128
+ } else {
129
+ return rb_hash_aref(rb_iv_get(self, "@features"), feature);
130
+ }
131
+ }
132
+
133
+ /* Set the feature to the supplied value. */
134
+ static VALUE birch_set(VALUE self, VALUE feature, VALUE value) {
135
+ return rb_hash_aset(rb_iv_get(self, "@features"), feature, value);
136
+ }
137
+
138
+ /* Unset a feature. */
139
+ static VALUE birch_unset(VALUE self, VALUE feature) {
140
+ return rb_hash_delete(
141
+ rb_iv_get(self, "@features"),
142
+ feature
143
+ );
144
+ }
145
+
146
+ /* Return the total number of nodes in the subtree */
147
+ static VALUE birch_size(VALUE self) {
148
+
149
+ VALUE children;
150
+ int sum;
151
+ long len;
152
+ long i;
153
+
154
+ children = rb_iv_get(self, "@children");
155
+ len = RARRAY_LEN(children);
156
+
157
+ sum = 0;
158
+ for (i=0; i<len; i++) {
159
+ sum += NUM2INT(rb_funcall(RARRAY_PTR(children)[i], rb_intern("size"), 0));
160
+ }
161
+
162
+ // subtree size is our node size (1) + all childen sizes
163
+ return INT2NUM(1 + sum);
164
+ }
165
+
166
+ /* Iterate over each children of the node. */
167
+ static VALUE birch_each(VALUE self) {
168
+
169
+ long i;
170
+ VALUE children;
171
+ children = rb_iv_get(self, "@children");
172
+
173
+ RETURN_ENUMERATOR(children, 0, 0);
174
+
175
+ for (i=0; i<RARRAY_LEN(children); i++) {
176
+ rb_yield(RARRAY_PTR(children)[i]);
177
+ }
178
+
179
+ return children;
180
+
181
+ }
182
+
183
+ static VALUE birch_find(VALUE self, VALUE id_or_node) {
184
+
185
+ VALUE id;
186
+ VALUE children_hash;
187
+ VALUE children;
188
+ VALUE result;
189
+ long i;
190
+
191
+ if (rb_obj_is_kind_of(id_or_node, birch_tree)) {
192
+ id = rb_iv_get(id_or_node, "@id");
193
+ } else { id = id_or_node; }
194
+
195
+ children_hash = rb_iv_get(self, "@children_hash");
196
+ result = rb_hash_aref(children_hash, id);
197
+
198
+ if (result == Qnil) {
199
+ children = rb_iv_get(self, "@children");
200
+ for (i=0; i < RARRAY_LEN(children); i++) {
201
+ result = rb_funcall(
202
+ RARRAY_PTR(children)[i],
203
+ rb_intern("find"), 1, id
204
+ );
205
+ if (result != Qnil) { return result; }
206
+ }
207
+ return Qnil;
208
+ } else { return result; }
209
+
210
+ }
211
+
212
+ /* Boolean - is this node's subtree empty? */
213
+ static VALUE birch_is_leaf(VALUE self) {
214
+ if (RARRAY_LEN(rb_iv_get(self, "@children")) == 0) {
215
+ return Qtrue;
216
+ } else {
217
+ return Qfalse;
218
+ }
219
+ }
220
+
221
+ /* Boolean - is this node parent-less? */
222
+ static VALUE birch_is_root(VALUE self) {
223
+ if (rb_iv_get(self, "@parent") == Qnil) {
224
+ return Qtrue;
225
+ } else {
226
+ return Qfalse;
227
+ }
228
+ }
229
+
230
+ /* Boolean - does this node have children */
231
+ static VALUE birch_has_children(VALUE self) {
232
+ if (RARRAY_LEN(rb_iv_get(self, "@children")) == 0) {
233
+ return Qfalse;
234
+ } else {
235
+ return Qtrue;
236
+ }
237
+ }
238
+
239
+ /* Boolean - does this node have children */
240
+ static VALUE birch_has_edges(VALUE self) {
241
+ if (RARRAY_LEN(rb_iv_get(self, "@edges")) == 0) {
242
+ return Qfalse;
243
+ } else {
244
+ return Qtrue;
245
+ }
246
+ }
247
+
248
+ /* Boolean - does the node have a parent? */
249
+ static VALUE birch_has_parent(VALUE self) {
250
+ if (rb_iv_get(self, "@parent") == Qnil) {
251
+ return Qfalse;
252
+ } else {
253
+ return Qtrue;
254
+ }
255
+ }
256
+
257
+ /* Boolean - does the node have the feature? */
258
+ static VALUE birch_has_feature(VALUE self, VALUE feature) {
259
+ VALUE features;
260
+ features = rb_iv_get(self, "@features");
261
+ if (rb_hash_aref(features, feature) == Qnil) {
262
+ return Qfalse;
263
+ } else {
264
+ return Qtrue;
265
+ }
266
+ }
267
+
268
+ /* Boolean - does the node have features? */
269
+ static VALUE birch_has_features(VALUE self) {
270
+ VALUE features;
271
+ features = rb_iv_get(self, "@features");
272
+ if (!RHASH(features)->ntbl) {
273
+ return Qfalse;
274
+ } else { return Qtrue; }
275
+ }
276
+
277
+
278
+ static VALUE birch_link(VALUE self, VALUE edge) {
279
+
280
+ VALUE edges;
281
+ edges = rb_iv_get(self, "@edges");
282
+
283
+ rb_funcall(
284
+ edges, rb_intern("push"), 1, edge
285
+ );
286
+
287
+ return edge;
288
+
289
+ }
290
+
291
+ /* Remove from parent and set as root */
292
+ static VALUE birch_set_as_root(VALUE self) {
293
+
294
+ // Set the parent to be nil.
295
+ rb_iv_set(self, "@parent", Qnil);
296
+
297
+ // Return self.
298
+ return Qnil;
299
+
300
+ }
301
+
302
+ /* Removes a node by ID and returns it */
303
+ static VALUE birch_remove(VALUE self, VALUE id) {
304
+
305
+ VALUE val;
306
+
307
+ // Delete the node from the hash and retrieve it.
308
+ val = rb_hash_delete(
309
+ rb_iv_get(self, "@children_hash"), id
310
+ );
311
+
312
+ // Raise an exception if the value can't be found.
313
+ if (val == Qnil) {
314
+ rb_raise(rb_eArgError,
315
+ "Given ID is not a children of this node.");
316
+ return Qnil;
317
+ }
318
+
319
+ // Delete the node from the children array.
320
+ rb_funcall(
321
+ rb_iv_get(self, "@children"),
322
+ rb_intern("delete"), 1, val
323
+ );
324
+
325
+ // Set the node as a root (set its parent to nil).
326
+ rb_funcall(
327
+ val, rb_intern("set_as_root!"), 0
328
+ );
329
+
330
+ return val;
331
+
332
+ }
333
+
334
+ /* Remove all children and set them as root. */
335
+ static VALUE birch_remove_all(VALUE self) {
336
+
337
+ VALUE children;
338
+ long i;
339
+ long children_len;
340
+
341
+ children = rb_iv_get(self, "@children");
342
+ children_len = RARRAY_LEN(children);
343
+
344
+ for (i = 0; i < children_len; i++) {
345
+ rb_funcall(
346
+ RARRAY_PTR(children)[i],
347
+ rb_intern("set_as_root!"), 0
348
+ );
349
+ }
350
+
351
+ rb_iv_set(self, "@children", rb_ary_new());
352
+ rb_iv_set(self, "@children_hash", rb_hash_new());
353
+
354
+ return Qnil;
355
+ }
356
+
357
+ /* This class is a node for an N-ary tree data structure
358
+ * with a unique identifier, text value, children, features
359
+ * (annotations) and dependencies.
360
+ *
361
+ * This class was partly based on the 'rubytree' gem.
362
+ * RubyTree is licensed under the BSD license and can
363
+ * be found at http://rubytree.rubyforge.org/rdoc/.
364
+ */
365
+ void Init_native(void) {
366
+
367
+ birch = rb_define_module("Birch");
368
+
369
+ /*
370
+ * Birch::Tree
371
+ */
372
+ birch_tree = rb_define_class_under(birch, "Tree", rb_cObject);
373
+
374
+ // Attribute accessors
375
+ rb_attr(birch_tree, rb_intern("id"), 1, 1, 1);
376
+ rb_attr(birch_tree, rb_intern("value"), 1, 1, 1);
377
+ rb_attr(birch_tree, rb_intern("parent"), 1, 1, 1);
378
+ rb_attr(birch_tree, rb_intern("features"), 1, 1, 1);
379
+
380
+ // Attribute readers
381
+ rb_attr(birch_tree, rb_intern("children"), 1, 0, 0);
382
+ rb_attr(birch_tree, rb_intern("edges"), 1, 0, 0);
383
+
384
+ // Methods
385
+ rb_define_method(birch_tree, "initialize", birch_initialize, 2);
386
+ rb_define_method(birch_tree, "root", birch_root, 0);
387
+ rb_define_method(birch_tree, "<<", birch_add, 1);
388
+ rb_define_method(birch_tree, "add", birch_add, 1);
389
+ rb_define_method(birch_tree, "[]", birch_get, 1);
390
+ rb_define_method(birch_tree, "get", birch_get, 1);
391
+ rb_define_method(birch_tree, "[]=", birch_set, 2);
392
+ rb_define_method(birch_tree, "set", birch_set, 2);
393
+ rb_define_method(birch_tree, "unset", birch_unset, 1);
394
+ rb_define_method(birch_tree, "size", birch_size, 0);
395
+ rb_define_method(birch_tree, "each", birch_each, 0);
396
+ rb_define_method(birch_tree, "find", birch_find, 1);
397
+ rb_define_method(birch_tree, "is_leaf?", birch_is_leaf, 0);
398
+ rb_define_method(birch_tree, "is_root?", birch_is_root, 0);
399
+ rb_define_method(birch_tree, "has_parent?", birch_has_parent, 0);
400
+ rb_define_method(birch_tree, "has_children?", birch_has_children, 0);
401
+ rb_define_method(birch_tree, "has_edges?", birch_has_edges, 0);
402
+ rb_define_method(birch_tree, "has_feature?", birch_has_feature, 1);
403
+ rb_define_method(birch_tree, "has_features?", birch_has_features, 0);
404
+ rb_define_method(birch_tree, "has?", birch_has_feature, 1);
405
+ rb_define_method(birch_tree, "link", birch_link, 1);
406
+ rb_define_method(birch_tree, "set_as_root!", birch_set_as_root, 0);
407
+ rb_define_method(birch_tree, "remove", birch_remove, 1);
408
+ rb_define_method(birch_tree, "remove_all!", birch_remove_all, 0);
409
+
410
+ /*
411
+ * Birch::Edge
412
+ */
413
+
414
+ birch_edge = rb_define_class_under(birch, "Edge", rb_cObject);
415
+
416
+ // Attribute readers
417
+ rb_attr(birch_edge, rb_intern("node_a"), 1, 0, 0);
418
+ rb_attr(birch_edge, rb_intern("node_b"), 1, 0, 0);
419
+ rb_attr(birch_edge, rb_intern("directed"), 1, 0, 0);
420
+ rb_attr(birch_edge, rb_intern("direction"), 1, 0, 0);
421
+
422
+ rb_define_method(birch_edge, "initialize", birch_edge_initialize, -1);
423
+
424
+ }
data/lib/birch/pure.rb ADDED
@@ -0,0 +1,132 @@
1
+ module Birch
2
+
3
+ class Tree
4
+
5
+ attr_accessor :id, :value
6
+ attr_accessor :parent, :features
7
+ attr_reader :children, :edges
8
+
9
+ def initialize(value, id)
10
+ @value, @id = value, id
11
+ @parent = nil
12
+ @children = []
13
+ @children_hash = {}
14
+ @features = {}
15
+ @edges = []
16
+ end
17
+
18
+ def root
19
+ @parent.nil? ? self : root(parent)
20
+ end
21
+
22
+ def add(node_or_nodes)
23
+ nodes = [node_or_nodes].flatten
24
+ nodes.each do |node|
25
+ @children << node
26
+ @children_hash[node.id] = node
27
+ node.parent = self
28
+ end
29
+ nodes.first
30
+ end
31
+ alias_method :<<, :add
32
+
33
+ def get(feature)
34
+ case feature
35
+ when :id
36
+ @id
37
+ when :value
38
+ @value
39
+ else
40
+ @features[feature]
41
+ end
42
+ end
43
+ alias_method :[], :get
44
+
45
+ def set(feature, value)
46
+ @features[feature] = value
47
+ end
48
+ alias_method :[]=, :set
49
+
50
+ def unset(feature)
51
+ @features.delete(feature)
52
+ end
53
+
54
+ def size
55
+ 1 + (@children.map(&:size).reduce(:+) || 0)
56
+ end
57
+
58
+ def each
59
+ @children.each{|c| yield c}
60
+ end
61
+
62
+ def find(id_or_node)
63
+ id = id_or_node.is_a?(Tree) ? id_or_node.id : id_or_node
64
+ return @children_hash[id] if @children_hash.has_key?(id)
65
+ @children.each{|c| r = c.find(id); return r if r}
66
+ nil
67
+ end
68
+
69
+ def is_leaf?; @children.empty?; end
70
+ def is_root?; @parent.nil?; end
71
+ def has_children?; !@children.empty?; end
72
+ def has_edges?; !@edges.empty?; end
73
+ def has_parent?; !@parent.nil? ;end
74
+ def has_features?; !@features.empty?; end
75
+
76
+ def has_feature?(feature)
77
+ @features.has_key?(feature)
78
+ end
79
+
80
+ alias_method :has?, :has_feature?
81
+
82
+ def link(edge)
83
+ @edges << edge
84
+ edge
85
+ end
86
+
87
+ def set_as_root!
88
+ if has_parent?
89
+ @parent = nil
90
+ else
91
+ raise "Node is already the root."
92
+ end
93
+ nil
94
+ end
95
+
96
+ def remove(id)
97
+ node = @children_hash.delete(id)
98
+ if node.nil?
99
+ raise ArgumentError,
100
+ "Given ID is not a children of this node."
101
+ end
102
+ @children.delete(node)
103
+ node.set_as_root!
104
+ node
105
+ end
106
+
107
+ def remove_all!
108
+ @children.each{|c| c.set_as_root!}
109
+ @children = []
110
+ @children_hash = {}
111
+ nil
112
+ end
113
+ end
114
+
115
+ class Edge
116
+ attr_reader :node_a, :node_b
117
+ attr_reader :directed, :direction
118
+
119
+ def initialize(node_a, node_b, directed = false, direction = 0)
120
+ unless [3, 4].include?(args.size)
121
+ raise ArgumentError, "Wrong number of arguments."
122
+ end
123
+ @node_a = args[0]
124
+ @node_b = args[1]
125
+ @directed = args[2]
126
+ @direction = args.size == 4 ? args[3] : nil
127
+ end
128
+ end
129
+
130
+ end
131
+
132
+
@@ -0,0 +1,3 @@
1
+ module Birch
2
+ VERSION = '0.0.4'
3
+ end
data/lib/birch.rb ADDED
@@ -0,0 +1,6 @@
1
+ if RUBY_PLATFORM =~ /java/
2
+ require 'birch/pure'
3
+ else
4
+ require 'birch/native'
5
+ end
6
+ require 'birch/version'
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: birch
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.4
6
+ platform: java
7
+ authors:
8
+ - Louis Mullie
9
+ - Colin Surprenant
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-12-13 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ version_requirements: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.12.0
22
+ none: false
23
+ requirement: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: 2.12.0
28
+ none: false
29
+ prerelease: false
30
+ type: :development
31
+ - !ruby/object:Gem::Dependency
32
+ name: rake
33
+ version_requirements: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ none: false
39
+ requirement: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ none: false
45
+ prerelease: false
46
+ type: :development
47
+ description: ! ' '
48
+ email:
49
+ - louis.mullie@gmail.com
50
+ - colin.surprenant@gmail.com
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - lib/birch.rb
56
+ - lib/birch/pure.rb
57
+ - lib/birch/version.rb
58
+ - ext/birch/native.c
59
+ - ext/birch/extconf.rb
60
+ homepage: https://github.com/louismullie/birch
61
+ licenses: []
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ none: false
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ none: false
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 1.8.24
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: A basic Ruby tree implementation with an optional C extension for speed.
84
+ test_files: []
85
+ ...