lib/continuum.rb in memcache-client-1.6.2 vs lib/continuum.rb in memcache-client-1.6.3
- old
+ new
@@ -1,32 +1,63 @@
module Continuum
POINTS_PER_SERVER = 160 # this is the default in libmemcached
- begin
- require 'binary_search' # try to load native extension
- rescue LoadError => e
- puts "Unable to load fast binary search, falling back to pure Ruby: #{e.message}"
+ class << self
- # slow but pure ruby version
- # Find the closest index in Continuum with value <= the given value
- def self.binary_search(ary, value, &block)
- upper = ary.size - 1
- lower = 0
- idx = 0
+ begin
+ require 'inline'
+ inline do |builder|
+ builder.c <<-EOM
+ int binary_search(VALUE ary, unsigned int r) {
+ int upper = RARRAY_LEN(ary) - 1;
+ int lower = 0;
+ int idx = 0;
+ ID value = rb_intern("value");
- while(lower <= upper) do
- idx = (lower + upper) / 2
- comp = ary[idx].value <=> value
-
- if comp == 0
- return idx
- elsif comp > 0
- upper = idx - 1
- else
- lower = idx + 1
+ while (lower <= upper) {
+ idx = (lower + upper) / 2;
+
+ VALUE continuumValue = rb_funcall(RARRAY_PTR(ary)[idx], value, 0);
+ unsigned int l = NUM2UINT(continuumValue);
+ if (l == r) {
+ return idx;
+ }
+ else if (l > r) {
+ upper = idx - 1;
+ }
+ else {
+ lower = idx + 1;
+ }
+ }
+ return upper;
+ }
+ EOM
+ end
+ rescue Exception => e
+ puts "Unable to generate native code, falling back to Ruby: #{e.message}"
+
+ # slow but pure ruby version
+ # Find the closest index in Continuum with value <= the given value
+ def binary_search(ary, value, &block)
+ upper = ary.size - 1
+ lower = 0
+ idx = 0
+
+ while(lower <= upper) do
+ idx = (lower + upper) / 2
+ comp = ary[idx].value <=> value
+
+ if comp == 0
+ return idx
+ elsif comp > 0
+ upper = idx - 1
+ else
+ lower = idx + 1
+ end
end
+ return upper
end
- return upper
+
end
end
class Entry