memcache 1.2.7 → 1.2.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +13 -0
- data/VERSION.yml +1 -1
- data/ext/native_server.c +70 -28
- data/lib/memcache.rb +12 -6
- data/lib/memcache/base.rb +2 -1
- data/memcache.gemspec +1 -1
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -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
|
|
data/VERSION.yml
CHANGED
data/ext/native_server.c
CHANGED
@@ -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
|
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
|
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
|
90
|
-
|
91
|
-
|
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(
|
94
|
-
|
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
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
551
|
-
id_md5
|
552
|
-
id_crc
|
553
|
-
id_fnv1_64
|
554
|
-
id_fnv1a_64
|
555
|
-
id_fnv1_32
|
556
|
-
id_fnv1a_32
|
557
|
-
id_jenkins
|
558
|
-
id_hsieh
|
559
|
-
id_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
|
|
data/lib/memcache.rb
CHANGED
@@ -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]
|
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 : :
|
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
|
data/lib/memcache/base.rb
CHANGED
@@ -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
|
62
|
+
raise Memcache::Error, "key too long #{key.inspect}" if key.length > 250
|
62
63
|
key
|
63
64
|
end
|
64
65
|
end
|
data/memcache.gemspec
CHANGED