memcache 1.2.7 → 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -221,6 +221,19 @@ NativeServer also accepts a few other options:
221
221
  is actually Jenkins's one-at-a-time hash), the default hashing method if you
222
222
  don't specify one is <tt>:crc</tt>.
223
223
 
224
+ [+distribution+] The libmemcached distribution method. See http://docs.tangent.org/libmemcached/index.html
225
+ for more detail. One of:
226
+
227
+ <tt>:modula :consistent :ketama :ketama_spy</tt>
228
+
229
+ NOTE: <tt>:modula</tt> is the default. internally, <tt>:consistent</tt>
230
+ is an alias for <tt>:ketama</tt>, and <tt>:ketama_spy</tt> provides
231
+ compatibility with the SPY Memcached client for Java.
232
+
233
+ [+ketama] Sets the default distribution to <tt>:ketama</tt> and hash to <tt>:md5</tt>.
234
+
235
+ [+ketama_wieghted] Enables ketama weighting and sets the default distribution to <tt>:ketama</tt> and hash to <tt>:md5</tt>.
236
+
224
237
  [+binary+] A boolean value specifying whether to use memcached's binary protocol instead
225
238
  of the default ascii protocol. This is slightly slower, but should allow you to use unicode keys.
226
239
 
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :build:
3
3
  :minor: 2
4
- :patch: 7
4
+ :patch: 8
5
5
  :major: 1
@@ -11,11 +11,15 @@ VALUE cMemcacheClientError;
11
11
  VALUE cMemcacheConnectionError;
12
12
  VALUE sym_host;
13
13
  VALUE sym_port;
14
+ VALUE sym_weight;
14
15
  VALUE sym_prefix;
15
16
  VALUE sym_hash;
16
17
  VALUE sym_hash_with_prefix;
18
+ VALUE sym_distribution;
17
19
  VALUE sym_binary;
18
20
  VALUE sym_servers;
21
+ VALUE sym_ketama;
22
+ VALUE sym_ketama_weighted;
19
23
 
20
24
  ID id_default;
21
25
  ID id_md5;
@@ -27,6 +31,10 @@ ID id_fnv1a_32;
27
31
  ID id_jenkins;
28
32
  ID id_hsieh;
29
33
  ID id_murmur;
34
+ ID id_modula;
35
+ ID id_consistent;
36
+ ID id_ketama;
37
+ ID id_ketama_spy;
30
38
 
31
39
  static ID iv_memcache_flags, iv_memcache_cas;
32
40
 
@@ -38,8 +46,7 @@ static VALUE mc_alloc(VALUE klass) {
38
46
  memcached_st *mc;
39
47
  VALUE obj;
40
48
 
41
- mc = memcached_create(NULL);
42
- /* memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_VERIFY_KEY, true); */
49
+ mc = memcached_create(NULL);
43
50
  memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_CACHE_LOOKUPS, true);
44
51
 
45
52
  obj = Data_Wrap_Struct(klass, 0, mc_free, mc);
@@ -77,21 +84,39 @@ static memcached_hash_t hash_behavior(VALUE sym) {
77
84
  rb_raise(cMemcacheError, "Invalid hash behavior");
78
85
  }
79
86
 
87
+ static memcached_hash_t distribution_behavior(VALUE sym) {
88
+ ID id = SYM2ID(sym);
89
+
90
+ if (id == id_modula ) return MEMCACHED_DISTRIBUTION_MODULA;
91
+ if (id == id_consistent ) return MEMCACHED_DISTRIBUTION_CONSISTENT;
92
+ if (id == id_ketama ) return MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA;
93
+ if (id == id_ketama_spy ) return MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY;
94
+ rb_raise(cMemcacheError, "Invalid distribution behavior");
95
+ }
96
+
80
97
  static VALUE mc_initialize(VALUE self, VALUE opts) {
81
98
  memcached_st *mc;
82
- VALUE hostv, portv, servers_aryv, prefixv, hashv;
83
- char* host;
84
- char* server;
85
- char* hashkit;
86
- int port, i;
99
+ VALUE servers_aryv, prefixv, hashv, distributionv;
87
100
 
88
101
  Data_Get_Struct(self, memcached_st, mc);
89
- hashv = rb_hash_aref(opts, sym_hash);
90
- prefixv = rb_hash_aref(opts, sym_prefix);
91
- servers_aryv = rb_hash_aref(opts, sym_servers);
102
+ hashv = rb_hash_aref(opts, sym_hash);
103
+ distributionv = rb_hash_aref(opts, sym_distribution);
104
+ prefixv = rb_hash_aref(opts, sym_prefix);
105
+ servers_aryv = rb_hash_aref(opts, sym_servers);
106
+
107
+ if (!NIL_P(hashv)) {
108
+ memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_HASH, hash_behavior(hashv));
109
+ memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_KETAMA_HASH, hash_behavior(hashv));
110
+ }
92
111
 
93
- if (!NIL_P(hashv))
94
- memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_HASH, hash_behavior(hashv));
112
+ if (!NIL_P(distributionv))
113
+ memcached_behavior_set_distribution(mc, distribution_behavior(distributionv));
114
+
115
+ if (RTEST( rb_hash_aref(opts, sym_ketama) ))
116
+ memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_KETAMA, true);
117
+
118
+ if (RTEST( rb_hash_aref(opts, sym_ketama_weighted) ))
119
+ memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, true);
95
120
 
96
121
  if (RTEST( rb_hash_aref(opts, sym_hash_with_prefix) ))
97
122
  memcached_behavior_set(mc, MEMCACHED_BEHAVIOR_HASH_WITH_PREFIX_KEY, true);
@@ -103,17 +128,26 @@ static VALUE mc_initialize(VALUE self, VALUE opts) {
103
128
  memcached_callback_set(mc, MEMCACHED_CALLBACK_PREFIX_KEY, STR2CSTR(prefixv));
104
129
 
105
130
  if (!NIL_P(servers_aryv)) {
131
+ char* server;
132
+ int i;
133
+
106
134
  for (i = 0; i < RARRAY(servers_aryv)->len; i++) {
107
135
  server = StringValuePtr(RARRAY(servers_aryv)->ptr[i]);
108
136
  memcached_server_push(mc, memcached_servers_parse(server));
109
137
  }
110
138
  } else {
111
- hostv = rb_hash_aref(opts, sym_host);
112
- portv = rb_hash_aref(opts, sym_port);
113
- host = StringValuePtr(hostv);
114
- port = NIL_P(portv) ? MEMCACHED_DEFAULT_PORT : NUM2INT(portv);
115
-
116
- memcached_server_add(mc, host, port);
139
+ VALUE hostv, portv, weightv;
140
+ char* host;
141
+ int port, weight;
142
+
143
+ hostv = rb_hash_aref(opts, sym_host);
144
+ portv = rb_hash_aref(opts, sym_port);
145
+ weightv = rb_hash_aref(opts, sym_weight);
146
+ host = StringValuePtr(hostv);
147
+ port = NIL_P(portv) ? MEMCACHED_DEFAULT_PORT : NUM2INT(portv);
148
+ weight = NIL_P(weightv) ? 0 : NUM2INT(weightv);
149
+
150
+ memcached_server_add_with_weight(mc, StringValuePtr(hostv), port, weight);
117
151
  }
118
152
 
119
153
  return self;
@@ -538,25 +572,33 @@ VALUE mc_close(VALUE self) {
538
572
  void Init_native_server() {
539
573
  sym_host = ID2SYM(rb_intern("host"));
540
574
  sym_port = ID2SYM(rb_intern("port"));
575
+ sym_weight = ID2SYM(rb_intern("weight"));
541
576
  sym_prefix = ID2SYM(rb_intern("prefix"));
542
577
  sym_hash = ID2SYM(rb_intern("hash"));
543
578
  sym_hash_with_prefix = ID2SYM(rb_intern("hash_with_prefix"));
579
+ sym_distribution = ID2SYM(rb_intern("distribution"));
544
580
  sym_binary = ID2SYM(rb_intern("binary"));
545
581
  sym_servers = ID2SYM(rb_intern("servers"));
582
+ sym_ketama = ID2SYM(rb_intern("ketama"));
583
+ sym_ketama_weighted = ID2SYM(rb_intern("ketama_weighted"));
546
584
 
547
585
  iv_memcache_flags = rb_intern("@memcache_flags");
548
586
  iv_memcache_cas = rb_intern("@memcache_cas");
549
587
 
550
- id_default = rb_intern("default");
551
- id_md5 = rb_intern("md5");
552
- id_crc = rb_intern("crc");
553
- id_fnv1_64 = rb_intern("fnv1_64");
554
- id_fnv1a_64 = rb_intern("fnv1a_64");
555
- id_fnv1_32 = rb_intern("fnv1_32");
556
- id_fnv1a_32 = rb_intern("fnv1a_32");
557
- id_jenkins = rb_intern("jenkins");
558
- id_hsieh = rb_intern("hsieh");
559
- id_murmur = rb_intern("murmur");
588
+ id_default = rb_intern("default");
589
+ id_md5 = rb_intern("md5");
590
+ id_crc = rb_intern("crc");
591
+ id_fnv1_64 = rb_intern("fnv1_64");
592
+ id_fnv1a_64 = rb_intern("fnv1a_64");
593
+ id_fnv1_32 = rb_intern("fnv1_32");
594
+ id_fnv1a_32 = rb_intern("fnv1a_32");
595
+ id_jenkins = rb_intern("jenkins");
596
+ id_hsieh = rb_intern("hsieh");
597
+ id_murmur = rb_intern("murmur");
598
+ id_modula = rb_intern("modula");
599
+ id_consistent = rb_intern("consistent");
600
+ id_ketama = rb_intern("ketama");
601
+ id_ketama_spy = rb_intern("ketama_spy");
560
602
 
561
603
  cMemcache = rb_define_class("Memcache", rb_cObject);
562
604
 
@@ -38,13 +38,12 @@ class Memcache
38
38
  @hash_with_prefix = opts[:hash_with_prefix].nil? ? true : opts[:hash_with_prefix]
39
39
 
40
40
  if opts[:native]
41
- native_opts = {}
41
+ native_opts = opts.clone
42
42
  native_opts[:servers] = (opts[:servers] || [ opts[:server] ]).collect do |server|
43
- server.is_a?(Hash) ? "#{server[:host]}:#{server[:port]}" : server
43
+ server.is_a?(Hash) ? "#{server[:host]}:#{server[:port]}:#{server[:weight]}" : server
44
44
  end
45
- native_opts[:hash] = opts[:hash] || :crc
45
+ native_opts[:hash] ||= :crc unless native_opts[:ketama] or native_opts[:ketama_wieghted]
46
46
  native_opts[:hash_with_prefix] = @hash_with_prefix
47
- native_opts[:binary] = opts[:binary]
48
47
 
49
48
  server_class = opts[:segment_large_values] ? SegmentedNativeServer : NativeServer
50
49
  @servers = [server_class.new(native_opts)]
@@ -239,6 +238,13 @@ class Memcache
239
238
  end
240
239
  end
241
240
 
241
+ def add_or_get(key, value, opts = {})
242
+ # Try to add, but if that fails, get the existing value.
243
+ add(key, value, opts)
244
+ rescue Memcache::Error
245
+ get(key)
246
+ end
247
+
242
248
  def get_some(keys, opts = {})
243
249
  keys = keys.collect {|key| key.to_s}
244
250
  records = opts[:disable] ? {} : self.multi_get(keys, opts)
@@ -249,10 +255,10 @@ class Memcache
249
255
  end
250
256
 
251
257
  keys_to_fetch = keys - records.keys
252
- method = opts[:overwrite] ? :set : :add
258
+ method = opts[:overwrite] ? :set : :add_or_get
253
259
  if keys_to_fetch.any?
254
260
  yield(keys_to_fetch).each do |key, value|
255
- self.send(method, key, value, opts) unless opts[:disable] or opts[:disable_write]
261
+ value = self.send(method, key, value, opts) unless opts[:disable] or opts[:disable_write]
256
262
  records[key] = value
257
263
  end
258
264
  end
@@ -57,8 +57,9 @@ class Memcache
57
57
  protected
58
58
 
59
59
  def cache_key(key)
60
+ raise Memcache::Error, "length zero key not permitted" if key.length == 0
60
61
  key = "#{prefix}#{key}"
61
- raise ArgumentError, "key too long #{key.inspect}" if key.length > 250
62
+ raise Memcache::Error, "key too long #{key.inspect}" if key.length > 250
62
63
  key
63
64
  end
64
65
  end
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{memcache}
8
- s.version = "1.2.7"
8
+ s.version = "1.2.8"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Justin Balthrop"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: memcache
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.7
4
+ version: 1.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Balthrop