From 523c6a46b06a726d63aa7a27840b79586f356bb5 Mon Sep 17 00:00:00 2001 From: codeout Date: Wed, 3 Oct 2012 20:57:13 +0900 Subject: Added a method 'nodes' to return all nodes in ruby's Hash. This is useful when a ruby code requires nodes list for example, and also it helps when we sort user data by prefix. [ew: minor compiler compatibility fixes] --- ext/rpatricia/rpatricia.c | 25 +++++++++++++++++++++++++ test.rb | 3 +++ test/test_nodes.rb | 29 +++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 test/test_nodes.rb diff --git a/ext/rpatricia/rpatricia.c b/ext/rpatricia/rpatricia.c index e1ae1df..03f6588 100644 --- a/ext/rpatricia/rpatricia.c +++ b/ext/rpatricia/rpatricia.c @@ -202,6 +202,30 @@ p_print_nodes (int argc, VALUE *argv, VALUE self) return Qtrue; } +static VALUE +p_nodes (VALUE self) +{ + VALUE buf = rb_str_new(0, 0); + char *cbuf; + patricia_tree_t *tree; + patricia_node_t *node; + VALUE hash; + + Data_Get_Struct(self, patricia_tree_t, tree); + + hash = rb_hash_new(); + if (tree->head) { + PATRICIA_WALK(tree->head, node) { + rb_str_resize(buf, PATRICIA_MAXSTRLEN); + cbuf = RSTRING_PTR(buf); + prefix_toa2x(node->prefix, cbuf, 1); + rb_str_set_len(buf, strlen(cbuf)); + rb_hash_aset(hash, buf, (VALUE)node->data); + } PATRICIA_WALK_END; + } + return hash; +} + static VALUE p_data (VALUE self) { @@ -385,6 +409,7 @@ Init_rpatricia (void) /* derivatives of climb */ rb_define_method(cPatricia, "num_nodes", p_num_nodes, 0); rb_define_method(cPatricia, "show_nodes", p_print_nodes, -1); + rb_define_method(cPatricia, "nodes", p_nodes, 0); /* destroy tree */ rb_define_method(cPatricia, "destroy", p_destroy, 0); diff --git a/test.rb b/test.rb index 09a11d0..6a2a066 100644 --- a/test.rb +++ b/test.rb @@ -60,4 +60,7 @@ my_test(4 == t.num_nodes) puts "test: showing all nodes" t.show_nodes +puts "test: return all nodes in Hash" +my_test(t.nodes == {"127.0.0.0/24"=>"", "192.168.1.0/24"=>"", "192.168.2.0/24"=>"", "192.168.3.100/32"=>""}) + t.destroy diff --git a/test/test_nodes.rb b/test/test_nodes.rb new file mode 100644 index 0000000..580a1f9 --- /dev/null +++ b/test/test_nodes.rb @@ -0,0 +1,29 @@ +require 'test/unit' +require 'rpatricia' + +class TestShowNodes < Test::Unit::TestCase + + def test_nodes + t = Patricia.new + string = "pref_10" + array = [:something] + t.add("127.0.0.0/24") + t.add("192.168.1.0/24") + t.add("192.168.2.0/24") + t.add("192.168.3.100") + t.add("10.0.0.0/8", string) + t.add("10.0.0.0/9", array) + + assert_equal({"10.0.0.0/8" => "pref_10", + "10.0.0.0/9" => [:something], + "127.0.0.0/24" => "", + "192.168.1.0/24" => "", + "192.168.2.0/24" => "", + "192.168.3.100/32" => ""}, + t.nodes) + + assert(string.object_id != t.nodes["10.0.0.0/8"].object_id) + assert(array.object_id == t.nodes["10.0.0.0/9"].object_id) + end + +end -- cgit v1.2.3-24-ge0c7