memcached 0.19.5 → 0.19.6

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
data/CHANGELOG CHANGED
@@ -1,4 +1,6 @@
1
1
 
2
+ v0.19.6. Add get_from_last.
3
+
2
4
  v0.19.5. Fix autoconf datestamps.
3
5
 
4
6
  v0.19.3. Add exception_retry_limit and exceptions_to_retry.
data/Manifest CHANGED
@@ -7,6 +7,7 @@ Rakefile
7
7
  TODO
8
8
  ext/extconf.rb
9
9
  ext/libmemcached-0.32.tar.gz
10
+ ext/libmemcached-2.patch
10
11
  ext/libmemcached.patch
11
12
  ext/rlibmemcached.i
12
13
  ext/rlibmemcached_wrap.c
data/Rakefile CHANGED
@@ -23,7 +23,7 @@ task :exceptions do
23
23
  end
24
24
 
25
25
  task :valgrind do
26
- exec("valgrind --tool=memcheck --leak-check=yes --show-reachable=no --num-callers=15 --track-fds=yes ruby #{File.dirname(__FILE__)}/test/profile/valgrind.rb")
26
+ exec("valgrind --tool=memcheck --leak-check=full --show-reachable=no --num-callers=15 --track-fds=yes --workaround-gcc296-bugs=yes --max-stackframe=7304328 --dsymutil=yes --track-origins=yes ruby #{File.dirname(__FILE__)}/test/profile/valgrind.rb")
27
27
  end
28
28
 
29
29
  task :profile do
@@ -5,7 +5,11 @@ HERE = File.expand_path(File.dirname(__FILE__))
5
5
  BUNDLE = Dir.glob("libmemcached-*.tar.gz").first
6
6
  BUNDLE_PATH = BUNDLE.sub(".tar.gz", "")
7
7
 
8
+ SOLARIS_32 = RbConfig::CONFIG['target'] == "i386-pc-solaris2.10"
9
+
8
10
  $CFLAGS = "#{RbConfig::CONFIG['CFLAGS']} #{$CFLAGS}".gsub("$(cflags)", "").gsub("-fno-common", "")
11
+ $CFLAGS << " -std=gnu99" if SOLARIS_32
12
+ $EXTRA_CONF = " --disable-64bit" if SOLARIS_32
9
13
  $LDFLAGS = "#{RbConfig::CONFIG['LDFLAGS']} #{$LDFLAGS}".gsub("$(ldflags)", "").gsub("-fno-common", "")
10
14
  $CXXFLAGS = " -std=gnu++98 #{$CFLAGS}"
11
15
  $CPPFLAGS = $ARCH_FLAG = $DLDFLAGS = ""
@@ -25,12 +29,14 @@ def check_libmemcached
25
29
  $CFLAGS = "#{$includes} #{$libraries} #{$CFLAGS}"
26
30
  $LDFLAGS = "#{$libraries} #{$LDFLAGS}"
27
31
  $LIBPATH = ["#{HERE}/lib"]
28
- $DEFLIBPATH = []
32
+ $DEFLIBPATH = [] unless SOLARIS_32
29
33
 
30
34
  Dir.chdir(HERE) do
31
35
  if File.exist?("lib")
32
36
  puts "Libmemcached already built; run 'rake clean' first if you need to rebuild."
33
37
  else
38
+ tar = SOLARIS_32 ? 'gtar' : 'tar'
39
+ patch = SOLARIS_32 ? 'gpatch' : 'patch'
34
40
 
35
41
  # have_sasl check may fail on OSX, skip it
36
42
  # unless RUBY_PLATFORM =~ /darwin/ or have_library('sasl2')
@@ -38,15 +44,19 @@ def check_libmemcached
38
44
  # end
39
45
 
40
46
  puts "Building libmemcached."
41
- puts(cmd = "tar xzf #{BUNDLE} 2>&1")
47
+ puts(cmd = "#{tar} xzf #{BUNDLE} 2>&1")
42
48
  raise "'#{cmd}' failed" unless system(cmd)
43
49
 
44
50
  puts "Patching libmemcached source."
45
- puts(cmd = "patch -p1 -Z < libmemcached.patch")
51
+ puts(cmd = "#{patch} -p1 -Z < libmemcached.patch")
46
52
  raise "'#{cmd}' failed" unless system(cmd)
47
53
 
48
54
  puts "Patching libmemcached with SASL support."
49
- puts(cmd = "patch -p1 -Z < sasl.patch")
55
+ puts(cmd = "#{patch} -p1 -Z < sasl.patch")
56
+ raise "'#{cmd}' failed" unless system(cmd)
57
+
58
+ puts "Patching libmemcached for get_from_last support."
59
+ puts(cmd = "#{patch} -p1 -Z < libmemcached-2.patch")
50
60
  raise "'#{cmd}' failed" unless system(cmd)
51
61
 
52
62
  puts "Touching aclocal.m4 in libmemcached."
@@ -0,0 +1,116 @@
1
+ diff --git a/libmemcached-0.32/libmemcached/memcached.h libmemcached/libmemcached/memcached.h
2
+ --- a/libmemcached-0.32/libmemcached/memcached.h
3
+ +++ b/libmemcached/libmemcached/memcached.h
4
+ @@ -119,6 +119,7 @@
5
+ #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
6
+ const sasl_callback_t *sasl_callbacks;
7
+ #endif
8
+ + int last_server_key;
9
+ };
10
+
11
+ LIBMEMCACHED_API
12
+ diff --git a/libmemcached-0.32/libmemcached/memcached_get.c libmemcached/libmemcached/memcached_get.c
13
+ --- a/libmemcached-0.32/libmemcached/memcached_get.c
14
+ +++ b/libmemcached/libmemcached/memcached_get.c
15
+ @@ -235,6 +235,8 @@
16
+ rc= MEMCACHED_SOME_ERRORS;
17
+ continue;
18
+ }
19
+ +
20
+ + ptr->last_server_key = server_key;
21
+ }
22
+
23
+ /*
24
+ @@ -256,6 +258,74 @@
25
+ return rc;
26
+ }
27
+
28
+ +
29
+ +char *memcached_get_from_last(memcached_st *ptr,
30
+ + const char *key,
31
+ + size_t key_length,
32
+ + size_t *value_length,
33
+ + uint32_t *flags,
34
+ + memcached_return *error)
35
+ +{
36
+ + memcached_return rc = MEMCACHED_NOTFOUND;
37
+ + char *value = NULL;
38
+ +
39
+ + if (memcached_server_response_count(&ptr->hosts[ptr->last_server_key]) == 0) {
40
+ + *error = memcached_connect(&ptr->hosts[ptr->last_server_key]);
41
+ +
42
+ + if (*error != MEMCACHED_SUCCESS) {
43
+ + return value;
44
+ + }
45
+ +
46
+ + if ((memcached_io_write(&ptr->hosts[ptr->last_server_key], "get ", 4, 0)) == -1) {
47
+ + *error = MEMCACHED_SOME_ERRORS;
48
+ + return value;
49
+ + }
50
+ + WATCHPOINT_ASSERT(ptr->hosts[ptr->last_server_key].cursor_active == 0);
51
+ + memcached_server_response_increment(&ptr->hosts[ptr->last_server_key]);
52
+ + WATCHPOINT_ASSERT(ptr->hosts[ptr->last_server_key].cursor_active == 1);
53
+ + }
54
+ +
55
+ + /* Only called when we have a prefix key */
56
+ + if (ptr->prefix_key[0] != 0) {
57
+ + if ((memcached_io_write(&ptr->hosts[ptr->last_server_key], ptr->prefix_key, ptr->prefix_key_length, 0)) == -1) {
58
+ + memcached_server_response_reset(&ptr->hosts[ptr->last_server_key]);
59
+ + *error = MEMCACHED_SOME_ERRORS;
60
+ + return value;
61
+ + }
62
+ + }
63
+ +
64
+ + if ((memcached_io_write(&ptr->hosts[ptr->last_server_key], key, key_length, 0)) == -1) {
65
+ + memcached_server_response_reset(&ptr->hosts[ptr->last_server_key]);
66
+ + *error = MEMCACHED_SOME_ERRORS;
67
+ + return value;
68
+ + }
69
+ +
70
+ + if ((memcached_io_write(&ptr->hosts[ptr->last_server_key], "\r\n", 2, 1)) == -1) {
71
+ + memcached_server_response_reset(&ptr->hosts[ptr->last_server_key]);
72
+ + *error = MEMCACHED_SOME_ERRORS;
73
+ + return value;
74
+ + }
75
+ +
76
+ + value = memcached_fetch(ptr, NULL, NULL, value_length, flags, error);
77
+ +
78
+ + /* This is for historical reasons */
79
+ + if (*error == MEMCACHED_END)
80
+ + *error = MEMCACHED_NOTFOUND;
81
+ +
82
+ + if (value != NULL) {
83
+ + size_t dummy_length;
84
+ + uint32_t dummy_flags;
85
+ + memcached_return dummy_error;
86
+ +
87
+ + (void)memcached_fetch(ptr, NULL, NULL,
88
+ + &dummy_length, &dummy_flags,
89
+ + &dummy_error);
90
+ + WATCHPOINT_ASSERT(dummy_length == 0);
91
+ + }
92
+ +
93
+ + return value;
94
+ +}
95
+ +
96
+ static memcached_return simple_binary_mget(memcached_st *ptr,
97
+ unsigned int master_server_key,
98
+ bool is_master_key_set,
99
+ diff --git a/libmemcached-0.32/libmemcached/memcached_get.h libmemcached/libmemcached/memcached_get.h
100
+ --- a/libmemcached-0.32/libmemcached/memcached_get.h
101
+ +++ b/libmemcached/libmemcached/memcached_get.h
102
+ @@ -53,7 +53,13 @@
103
+ memcached_result_st *result,
104
+ memcached_return *error);
105
+
106
+ -
107
+ +LIBMEMCACHED_API
108
+ +char *memcached_get_from_last(memcached_st *ptr,
109
+ + const char *key,
110
+ + size_t key_length,
111
+ + size_t *value_length,
112
+ + uint32_t *flags,
113
+ + memcached_return *error);
114
+
115
+ #ifdef __cplusplus
116
+ }
@@ -163,6 +163,18 @@ VALUE memcached_get_rvalue(memcached_st *ptr, const char *key, size_t key_length
163
163
  };
164
164
  %}
165
165
 
166
+ VALUE memcached_get_from_last_rvalue(memcached_st *ptr, const char *key, size_t key_length, uint32_t *flags, memcached_return *error);
167
+ %{
168
+ VALUE memcached_get_from_last_rvalue(memcached_st *ptr, const char *key, size_t key_length, uint32_t *flags, memcached_return *error) {
169
+ VALUE ret;
170
+ size_t value_length;
171
+ char *value = memcached_get_from_last(ptr, key, key_length, &value_length, flags, error);
172
+ ret = rb_str_new(value, value_length);
173
+ free(value);
174
+ return ret;
175
+ };
176
+ %}
177
+
166
178
  // Multi get
167
179
  VALUE memcached_fetch_rvalue(memcached_st *ptr, char *key, size_t *key_length, uint32_t *flags, memcached_return *error);
168
180
  %{
@@ -2228,6 +2228,15 @@ VALUE memcached_get_rvalue(memcached_st *ptr, const char *key, size_t key_length
2228
2228
  return ret;
2229
2229
  };
2230
2230
 
2231
+ VALUE memcached_get_from_last_rvalue(memcached_st *ptr, const char *key, size_t key_length, uint32_t *flags, memcached_return *error) {
2232
+ VALUE ret;
2233
+ size_t value_length;
2234
+ char *value = memcached_get_from_last(ptr, key, key_length, &value_length, flags, error);
2235
+ ret = rb_str_new(value, value_length);
2236
+ free(value);
2237
+ return ret;
2238
+ };
2239
+
2231
2240
 
2232
2241
  VALUE memcached_fetch_rvalue(memcached_st *ptr, char *key, size_t *key_length, uint32_t *flags, memcached_return *error) {
2233
2242
  size_t value_length;
@@ -12211,6 +12220,55 @@ fail:
12211
12220
  return Qnil;
12212
12221
  }
12213
12222
 
12223
+ SWIGINTERN VALUE
12224
+ _wrap_memcached_get_from_last_rvalue(int argc, VALUE *argv, VALUE self) {
12225
+ memcached_st *arg1 = (memcached_st *) 0 ;
12226
+ char *arg2 = (char *) 0 ;
12227
+ size_t arg3 ;
12228
+ uint32_t *arg4 = (uint32_t *) 0 ;
12229
+ memcached_return *arg5 = (memcached_return *) 0 ;
12230
+ void *argp1 = 0 ;
12231
+ int res1 = 0 ;
12232
+ uint32_t temp4 ;
12233
+ int res4 = SWIG_TMPOBJ ;
12234
+ memcached_return temp5 ;
12235
+ int res5 = SWIG_TMPOBJ ;
12236
+ VALUE result;
12237
+ VALUE vresult = Qnil;
12238
+
12239
+ arg4 = &temp4;
12240
+ arg5 = &temp5;
12241
+ if ((argc < 2) || (argc > 2)) {
12242
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)",argc); SWIG_fail;
12243
+ }
12244
+ res1 = SWIG_ConvertPtr(argv[0], &argp1,SWIGTYPE_p_memcached_st, 0 | 0 );
12245
+ if (!SWIG_IsOK(res1)) {
12246
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "memcached_st *","memcached_get_from_last_rvalue", 1, argv[0] ));
12247
+ }
12248
+ arg1 = (memcached_st *)(argp1);
12249
+ {
12250
+ arg2 = StringValuePtr(argv[1]);
12251
+ arg3 = (size_t) RSTRING_LEN(argv[1]);
12252
+ }
12253
+ result = (VALUE)memcached_get_from_last_rvalue(arg1,(char const *)arg2,arg3,arg4,arg5);
12254
+ vresult = result;
12255
+ if (SWIG_IsTmpObj(res4)) {
12256
+ vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_From_unsigned_SS_int((*arg4)));
12257
+ } else {
12258
+ int new_flags = SWIG_IsNewObj(res4) ? (SWIG_POINTER_OWN | 0 ) : 0 ;
12259
+ vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_NewPointerObj((void*)(arg4), SWIGTYPE_p_uint32_t, new_flags));
12260
+ }
12261
+ if (SWIG_IsTmpObj(res5)) {
12262
+ vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_From_unsigned_SS_short((*arg5)));
12263
+ } else {
12264
+ int new_flags = SWIG_IsNewObj(res5) ? (SWIG_POINTER_OWN | 0 ) : 0 ;
12265
+ vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_NewPointerObj((void*)(arg5), SWIGTYPE_p_memcached_return, new_flags));
12266
+ }
12267
+ return vresult;
12268
+ fail:
12269
+ return Qnil;
12270
+ }
12271
+
12214
12272
 
12215
12273
  SWIGINTERN VALUE
12216
12274
  _wrap_memcached_fetch_rvalue(int argc, VALUE *argv, VALUE self) {
@@ -13276,6 +13334,7 @@ SWIGEXPORT void Init_rlibmemcached(void) {
13276
13334
  rb_define_module_function(mRlibmemcached, "memcached_get_sasl_callbacks", _wrap_memcached_get_sasl_callbacks, -1);
13277
13335
  rb_define_module_function(mRlibmemcached, "memcached_sasl_authenticate_connection", _wrap_memcached_sasl_authenticate_connection, -1);
13278
13336
  rb_define_module_function(mRlibmemcached, "memcached_get_rvalue", _wrap_memcached_get_rvalue, -1);
13337
+ rb_define_module_function(mRlibmemcached, "memcached_get_from_last_rvalue", _wrap_memcached_get_from_last_rvalue, -1);
13279
13338
  rb_define_module_function(mRlibmemcached, "memcached_fetch_rvalue", _wrap_memcached_fetch_rvalue, -1);
13280
13339
  rb_define_module_function(mRlibmemcached, "memcached_stat_get_rvalue", _wrap_memcached_stat_get_rvalue, -1);
13281
13340
  rb_define_module_function(mRlibmemcached, "memcached_select_server_at", _wrap_memcached_select_server_at, -1);
@@ -502,9 +502,11 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
502
502
  keys.each do
503
503
  value, key, flags, ret = Lib.memcached_fetch_rvalue(@struct)
504
504
  break if ret == Lib::MEMCACHED_END
505
- check_return_code(ret, key)
506
- # Assign the value
507
- hash[key] = (marshal ? Marshal.load(value) : value)
505
+ if ret != Lib::MEMCACHED_NOTFOUND
506
+ check_return_code(ret, key)
507
+ # Assign the value
508
+ hash[key] = (marshal ? Marshal.load(value) : value)
509
+ end
508
510
  end
509
511
  hash
510
512
  else
@@ -520,6 +522,14 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
520
522
  retry
521
523
  end
522
524
 
525
+ # Gets a key's value from the previous server. Only useful with random distribution.
526
+ def get_from_last(key, marshal=true)
527
+ raise ArgumentError, "get_from_last() is not useful unless :random distribution is enabled." unless options[:distribution] == :random
528
+ value, flags, ret = Lib.memcached_get_from_last_rvalue(@struct, key)
529
+ check_return_code(ret, key)
530
+ marshal ? Marshal.load(value) : value
531
+ end
532
+
523
533
  ### Information methods
524
534
 
525
535
  # Return the server used by a particular key.
@@ -586,12 +596,14 @@ Please note that when <tt>:no_block => true</tt>, update methods do not raise on
586
596
  message = "Key #{inspect_keys(key, (detect_failure if ret == Lib::MEMCACHED_SERVER_MARKED_DEAD)).inspect}"
587
597
  if key.is_a?(String)
588
598
  if ret == Lib::MEMCACHED_ERRNO
589
- server = Lib.memcached_server_by_key(@struct, key)
590
- errno = server.first.cached_errno
591
- message = "Errno #{errno}: #{ERRNO_HASH[errno].inspect}. #{message}"
599
+ if (server = Lib.memcached_server_by_key(@struct, key)).is_a?(Array)
600
+ errno = server.first.cached_errno
601
+ message = "Errno #{errno}: #{ERRNO_HASH[errno].inspect}. #{message}"
602
+ end
592
603
  elsif ret == Lib::MEMCACHED_SERVER_ERROR
593
- server = Lib.memcached_server_by_key(@struct, key)
594
- message = "\"#{server.first.cached_server_error}\". #{message}."
604
+ if (server = Lib.memcached_server_by_key(@struct, key)).is_a?(Array)
605
+ message = "\"#{server.first.cached_server_error}\". #{message}."
606
+ end
595
607
  end
596
608
  end
597
609
  raise EXCEPTIONS[ret], message
@@ -7,7 +7,10 @@ class Memcached
7
7
  # A legacy compatibility wrapper for the Memcached class. It has basic compatibility with the <b>memcache-client</b> API.
8
8
  class Rails < ::Memcached
9
9
 
10
- DEFAULTS[:logger] = nil
10
+ DEFAULTS = {
11
+ :logger => nil,
12
+ :string_return_types => false
13
+ }
11
14
 
12
15
  attr_reader :logger
13
16
 
@@ -46,7 +49,9 @@ class Memcached
46
49
  # Wraps Memcached#cas so that it doesn't raise. Doesn't set anything if no value is present.
47
50
  def cas(key, ttl=@default_ttl, raw=false, &block)
48
51
  super(key, ttl, !raw, &block)
52
+ true
49
53
  rescue NotFound
54
+ false
50
55
  end
51
56
 
52
57
  alias :compare_and_swap :cas
@@ -59,21 +64,24 @@ class Memcached
59
64
  # Wraps Memcached#set.
60
65
  def set(key, value, ttl=@default_ttl, raw=false)
61
66
  super(key, value, ttl, !raw)
67
+ true
68
+ rescue NotStored
69
+ false
62
70
  end
63
71
 
64
72
  # Alternative to #set. Accepts a key, value, and an optional options hash supporting the
65
73
  # options :raw and :ttl.
66
74
  def write(key, value, options = {})
67
75
  set(key, value, options[:ttl] || @default_ttl, options[:raw])
68
- true
69
76
  end
70
77
 
71
78
  # Wraps Memcached#add so that it doesn't raise.
72
79
  def add(key, value, ttl=@default_ttl, raw=false)
73
80
  super(key, value, ttl, !raw)
74
- true
81
+ # This causes me physical pain.
82
+ opts[:string_return_types] ? "STORED\r\n" : true
75
83
  rescue NotStored
76
- false
84
+ opts[:string_return_types] ? "NOT STORED\r\n" : false
77
85
  end
78
86
 
79
87
  # Wraps Memcached#delete so that it doesn't raise.
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{memcached}
5
- s.version = "0.19.5"
5
+ s.version = "0.19.6"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Evan Weaver"]
9
9
  s.cert_chain = ["/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-public_cert.pem"]
10
- s.date = %q{2010-05-20}
10
+ s.date = %q{2010-06-13}
11
11
  s.description = %q{An interface to the libmemcached C client.}
12
12
  s.email = %q{}
13
13
  s.extensions = ["ext/extconf.rb"]
14
14
  s.extra_rdoc_files = ["BENCHMARKS", "CHANGELOG", "LICENSE", "README", "TODO", "lib/memcached.rb", "lib/memcached/behaviors.rb", "lib/memcached/exceptions.rb", "lib/memcached/memcached.rb", "lib/memcached/rails.rb"]
15
- s.files = ["BENCHMARKS", "CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "TODO", "ext/extconf.rb", "ext/libmemcached-0.32.tar.gz", "ext/libmemcached.patch", "ext/rlibmemcached.i", "ext/rlibmemcached_wrap.c", "ext/sasl.patch", "lib/memcached.rb", "lib/memcached/auth.rb", "lib/memcached/behaviors.rb", "lib/memcached/exceptions.rb", "lib/memcached/integer.rb", "lib/memcached/memcached.rb", "lib/memcached/rails.rb", "test/profile/benchmark.rb", "test/profile/profile.rb", "test/profile/valgrind.rb", "test/setup.rb", "test/teardown.rb", "test/test_helper.rb", "test/unit/binding_test.rb", "test/unit/memcached_test.rb", "test/unit/rails_test.rb", "memcached.gemspec"]
15
+ s.files = ["BENCHMARKS", "CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "TODO", "ext/extconf.rb", "ext/libmemcached-0.32.tar.gz", "ext/libmemcached-2.patch", "ext/libmemcached.patch", "ext/rlibmemcached.i", "ext/rlibmemcached_wrap.c", "ext/sasl.patch", "lib/memcached.rb", "lib/memcached/auth.rb", "lib/memcached/behaviors.rb", "lib/memcached/exceptions.rb", "lib/memcached/integer.rb", "lib/memcached/memcached.rb", "lib/memcached/rails.rb", "test/profile/benchmark.rb", "test/profile/profile.rb", "test/profile/valgrind.rb", "test/setup.rb", "test/teardown.rb", "test/test_helper.rb", "test/unit/binding_test.rb", "test/unit/memcached_test.rb", "test/unit/rails_test.rb", "memcached.gemspec"]
16
16
  s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/memcached/}
17
17
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Memcached", "--main", "README"]
18
18
  s.require_paths = ["lib", "ext"]
@@ -5,6 +5,8 @@ $LOAD_PATH << "#{File.dirname(__FILE__)}/../../lib/"
5
5
  require 'memcached'
6
6
  require 'rubygems'
7
7
 
8
+ GC.copy_on_write_friendly = true if GC.respond_to?("copy_on_write_friendly=")
9
+
8
10
  class Worker
9
11
  def initialize(method_name, iterations)
10
12
  @method = method_name || 'mixed'
@@ -255,6 +255,16 @@ class MemcachedTest < Test::Unit::TestCase
255
255
  assert_equal nil, result
256
256
  end
257
257
 
258
+ def test_get_from_last
259
+ cache = Memcached.new(@servers, :distribution => :random)
260
+ 10.times do |n|
261
+ cache.set key, n
262
+ end
263
+ 10.times do
264
+ assert_equal cache.get(key), cache.get_from_last(key)
265
+ end
266
+ end
267
+
258
268
  def test_get_missing
259
269
  @cache.delete key rescue nil
260
270
  assert_raise(Memcached::NotFound) do
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 19
8
- - 5
9
- version: 0.19.5
8
+ - 6
9
+ version: 0.19.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Evan Weaver
@@ -35,7 +35,7 @@ cert_chain:
35
35
  yZ0=
36
36
  -----END CERTIFICATE-----
37
37
 
38
- date: 2010-05-20 00:00:00 -07:00
38
+ date: 2010-06-13 00:00:00 -07:00
39
39
  default_executable:
40
40
  dependencies: []
41
41
 
@@ -66,6 +66,7 @@ files:
66
66
  - TODO
67
67
  - ext/extconf.rb
68
68
  - ext/libmemcached-0.32.tar.gz
69
+ - ext/libmemcached-2.patch
69
70
  - ext/libmemcached.patch
70
71
  - ext/rlibmemcached.i
71
72
  - ext/rlibmemcached_wrap.c
metadata.gz.sig CHANGED
Binary file