about summary refs log tree commit
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-09-02 13:56:39 -0700
committerEric Wong <normalperson@yhbt.net>2010-09-02 13:56:39 -0700
commit03daddf53a88bf1a3b7890d02577dd8921d70b76 (patch)
treeb98837aa15f79b0ab34cd7fe4bc433223ef6ad9d
parent531c7ee4fade42ff115ba9df9ca1ca7d7ad631d6 (diff)
downloadrpatricia-03daddf53a88bf1a3b7890d02577dd8921d70b76.tar.gz
add Patricia#include? method
This behaves like Patricia#match_best, but is more
efficient as it does not need to allocate a new object
on successful matches.
-rw-r--r--README8
-rw-r--r--ext/rpatricia/rpatricia.c18
-rw-r--r--test/test_include.rb25
3 files changed, 51 insertions, 0 deletions
diff --git a/README b/README
index 23ce6c1..0f9c012 100644
--- a/README
+++ b/README
@@ -124,6 +124,14 @@ search_exact:
 
 match_exact:        An alias of search_exact.
 
+include?:
+
+      pt.include?(key_string);
+
+    This method behaves like match_best, but returns true on success
+    and false on failure.  This method is more efficient than match_best
+    as it does not allocate a new object.
+
 remove:
 
       pt.remove(key_string);
diff --git a/ext/rpatricia/rpatricia.c b/ext/rpatricia/rpatricia.c
index 866572c..2c3fcc9 100644
--- a/ext/rpatricia/rpatricia.c
+++ b/ext/rpatricia/rpatricia.c
@@ -118,6 +118,21 @@ p_match (VALUE self, VALUE r_key)
 }
 
 static VALUE
+p_include (VALUE self, VALUE r_key)
+{
+  patricia_tree_t *tree;
+  patricia_node_t *node;
+  prefix_t *prefix;
+
+  Data_Get_Struct(self, patricia_tree_t, tree);
+  prefix = my_ascii2prefix (AF_INET, r_key);
+  node = patricia_search_best(tree, prefix);
+  Deref_Prefix (prefix);
+
+  return node ? Qtrue : Qfalse;
+}
+
+static VALUE
 p_match_exact (VALUE self, VALUE r_key)
 {
   patricia_tree_t *tree;
@@ -304,6 +319,9 @@ Init_rpatricia (void)
   rb_define_method(cPatricia, "match_exact", p_match_exact, 1);
   rb_define_method(cPatricia, "search_exact", p_match_exact, 1);
 
+  /* check existence */
+  rb_define_method(cPatricia, "include?", p_include, 1);
+
   /* removal */
   rb_define_method(cPatricia, "remove", p_remove, 1);
   rb_define_method(cPatricia, "remove_node", p_remove, 1);
diff --git a/test/test_include.rb b/test/test_include.rb
new file mode 100644
index 0000000..303ad46
--- /dev/null
+++ b/test/test_include.rb
@@ -0,0 +1,25 @@
+require 'test/unit'
+require 'rpatricia'
+
+class TestInclude < Test::Unit::TestCase
+
+  def setup
+    @t = Patricia.new
+  end
+
+  def test_include_exact
+    @t.add '127.0.0.1'
+    assert_equal true, @t.include?('127.0.0.1')
+    assert_equal false, @t.include?('127.0.0.2')
+    @t.clear
+    assert_equal false, @t.include?('127.0.0.1')
+  end
+
+  def test_include_match_prefix
+    @t.add '127.0.0.0/8'
+    assert_equal true, @t.include?('127.0.0.32')
+    assert_equal false, @t.include?('12.0.0.32')
+    @t.clear
+    assert_equal false, @t.include?('127.0.0.32')
+  end
+end