From b6165944348cd385e0b154debf0d05cc3241964a Mon Sep 17 00:00:00 2001 From: Evan Weaver Date: Wed, 23 Feb 2011 15:13:07 -0800 Subject: [PATCH] Speed up multiget. Don't cast types on unmarshalled set. --- lib/memcached/memcached.rb | 24 ++++++++++++------------ test/profile/benchmark.rb | 4 ++++ test/unit/memcached_test.rb | 31 +++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/lib/memcached/memcached.rb b/lib/memcached/memcached.rb index 8e7c005..6981506 100644 --- a/lib/memcached/memcached.rb +++ b/lib/memcached/memcached.rb @@ -308,7 +308,7 @@ Please note that when :no_block => true, update methods do not raise on # Also accepts a marshal value, which defaults to true. Set marshal to false if you want the value to be set directly. # def set(key, value, ttl=@default_ttl, marshal=true, flags=FLAGS) - value = marshal ? Marshal.dump(value) : value.to_s + value = marshal ? Marshal.dump(value) : value begin check_return_code( Lib.memcached_set(@struct, key, value, ttl, flags), @@ -325,7 +325,7 @@ Please note that when :no_block => true, update methods do not raise on # Add a key/value pair. Raises Memcached::NotStored if the key already exists on the server. The parameters are the same as set. def add(key, value, ttl=@default_ttl, marshal=true, flags=FLAGS) - value = marshal ? Marshal.dump(value) : value.to_s + value = marshal ? Marshal.dump(value) : value begin check_return_code( Lib.memcached_add(@struct, key, value, ttl, flags), @@ -374,7 +374,7 @@ Please note that when :no_block => true, update methods do not raise on # Replace a key/value pair. Raises Memcached::NotFound if the key does not exist on the server. The parameters are the same as set. def replace(key, value, ttl=@default_ttl, marshal=true, flags=FLAGS) - value = marshal ? Marshal.dump(value) : value.to_s + value = marshal ? Marshal.dump(value) : value begin check_return_code( Lib.memcached_replace(@struct, key, value, ttl, flags), @@ -504,14 +504,14 @@ Please note that when :no_block => true, update methods do not raise on check_return_code(ret, keys) hash = {} - keys.each do - value, key, flags, ret = Lib.memcached_fetch_rvalue(@struct) - break if ret == Lib::MEMCACHED_END - if ret != Lib::MEMCACHED_NOTFOUND - check_return_code(ret, key) - # Assign the value + value, key, flags, ret = Lib.memcached_fetch_rvalue(@struct) + while ret != 21 do # Lib::MEMCACHED_END + if ret == 0 # Lib::MEMCACHED_SUCCESS hash[key] = (marshal ? Marshal.load(value) : value) + elsif ret != 16 # Lib::MEMCACHED_NOTFOUND + check_return_code(ret, key) end + value, key, flags, ret = Lib.memcached_fetch_rvalue(@struct) end hash else @@ -592,10 +592,10 @@ Please note that when :no_block => true, update methods do not raise on # Checks the return code from Rlibmemcached against the exception list. Raises the corresponding exception if the return code is not Memcached::Success or Memcached::ActionQueued. Accepts an integer return code and an optional key, for exception messages. def check_return_code(ret, key = nil) #:doc: if ret == 0 # Memcached::Success - elsif ret == Lib::MEMCACHED_BUFFERED # Memcached::ActionQueued - elsif ret == Lib::MEMCACHED_NOTFOUND and @not_found + elsif ret == 32 # Lib::MEMCACHED_BUFFERED # Memcached::ActionQueued + elsif ret == 16 # Lib::MEMCACHED_NOTFOUND and @not_found raise @not_found - elsif ret == Lib::MEMCACHED_NOTSTORED and @not_stored + elsif ret == 14 # Lib::MEMCACHED_NOTSTORED and @not_stored raise @not_stored else message = "Key #{inspect_keys(key, (detect_failure if ret == Lib::MEMCACHED_SERVER_MARKED_DEAD)).inspect}" diff --git a/test/profile/benchmark.rb b/test/profile/benchmark.rb index 184d4c8..51ee4d0 100644 --- a/test/profile/benchmark.rb +++ b/test/profile/benchmark.rb @@ -120,8 +120,12 @@ class Bench end def benchmark_clients(test_name, populate_keys = true) + return if ENV["TEST"] and !test_name.include?(ENV["TEST"]) + @clients.keys.sort.each do |client_name| + next if ENV["CLIENT"] and !client_name.include?(ENV["CLIENT"]) next if client_name == "stash" and test_name == "set-large" # Don't let stash break the world + client = @clients[client_name] begin if populate_keys diff --git a/test/unit/memcached_test.rb b/test/unit/memcached_test.rb index 5aa8f88..f080fe2 100644 --- a/test/unit/memcached_test.rb +++ b/test/unit/memcached_test.rb @@ -177,9 +177,8 @@ class MemcachedTest < Test::Unit::TestCase end def test_initialize_with_backtraces - cache = Memcached.new @servers, - :show_backtraces => true - cache.delete key rescue + cache = Memcached.new @servers, :show_backtraces => true + cache.delete key rescue nil begin cache.get key rescue Memcached::NotFound => e @@ -404,9 +403,21 @@ class MemcachedTest < Test::Unit::TestCase assert_equal @marshalled_value, result end + def test_set_unmarshalled_and_get_unmarshalled + @cache.set key, @marshalled_value, 0, false + result = @cache.get key, false + assert_equal @marshalled_value, result + end + + def test_set_unmarshalled_error + assert_raises(TypeError) do + @cache.set key, @value, 0, false + end + end + def test_get_multi_unmarshalled - @cache.set "#{key}_1", 1, 0, false - @cache.set "#{key}_2", 2, 0, false + @cache.set "#{key}_1", "1", 0, false + @cache.set "#{key}_2", "2", 0, false assert_equal( {"#{key}_1" => "1", "#{key}_2" => "2"}, @cache.get(["#{key}_1", "#{key}_2"], false) @@ -415,7 +426,7 @@ class MemcachedTest < Test::Unit::TestCase def test_get_multi_mixed_marshalling @cache.set "#{key}_1", 1 - @cache.set "#{key}_2", 2, 0, false + @cache.set "#{key}_2", "2", 0, false assert_nothing_raised do @cache.get(["#{key}_1", "#{key}_2"], false) end @@ -566,12 +577,12 @@ class MemcachedTest < Test::Unit::TestCase # Increment and decrement def test_increment - @cache.set key, 10, 0, false + @cache.set key, "10", 0, false assert_equal 11, @cache.increment(key) end def test_increment_offset - @cache.set key, 10, 0, false + @cache.set key, "10", 0, false assert_equal 15, @cache.increment(key, 5) end @@ -583,12 +594,12 @@ class MemcachedTest < Test::Unit::TestCase end def test_decrement - @cache.set key, 10, 0, false + @cache.set key, "10", 0, false assert_equal 9, @cache.decrement(key) end def test_decrement_offset - @cache.set key, 10, 0, false + @cache.set key, "10", 0, false assert_equal 5, @cache.decrement(key, 5) end