CAS support, as long as you patch libmemcached to send the right operator.

This commit is contained in:
Evan Weaver 2008-02-14 04:24:36 +00:00
Родитель 8b3822363b
Коммит 92454b4bda
4 изменённых файлов: 793 добавлений и 532 удалений

Просмотреть файл

@ -16,6 +16,7 @@
%apply unsigned short { uint8_t };
%apply unsigned int { uint16_t };
%apply unsigned long { uint32_t flags, uint32_t offset };
/* %apply unsigned long long { uint64_t cas }; */
// For behavior's weird set interface
@ -63,6 +64,7 @@
//// Output maps
/* %apply unsigned long long { uint64_t cas }; */
%apply unsigned short *OUTPUT {memcached_return *error}
%apply unsigned int *OUTPUT {uint32_t *flags}
%apply size_t *OUTPUT {size_t *value_length}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -48,7 +48,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
=end
def initialize(servers, opts = {})
@struct = Lib::MemcachedSt.new
@struct = Lib::MemcachedSt.new
Lib.memcached_create(@struct)
# Servers
@ -104,6 +104,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
def destroy(disable_methods = true)
Lib.memcached_free(@struct)
@struct = nil
if disable_methods
class << self
Memcached.instance_methods.each do |method_name|
@ -215,17 +216,22 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
)
end
# Not yet implemented.
#
# Reads a key's value from the server and yields it to a block. Replaces the key's value with the result of the block as long as the key hasn't been updated in the meantime, otherwise raises <b>Memcached::NotStored</b>. Accepts a String <tt>key</tt> and a block.
#
# Also accepts an optional <tt>timeout</tt> value.
#
# CAS stands for "compare and swap", and avoids the need for manual key mutexing. CAS support must be enabled in Memcached.new or a <b>Memcached::ClientError</b> will be raised.
def cas(*args)
# Requires memcached HEAD
raise NotImplemented
# CAS stands for "compare and swap", and avoids the need for manual key mutexing. CAS support must be enabled in Memcached.new or a <b>Memcached::ClientError</b> will be raised. Note that CAS may be buggy in memcached itself.
#
def cas(key, timeout = 0, marshal = true)
raise ClientError, "CAS not enabled for this Memcached instance" unless options[:support_cas]
value = get(key)
value = yield value
value = marshal ? Marshal.dump(value) : value.to_s
check_return_code(
Lib.memcached_cas(@struct, Lib.ns(@namespace, key), value, timeout, FLAGS, @struct.result.cas)
)
end
### Deleters

Просмотреть файл

@ -336,29 +336,38 @@ class MemcachedTest < Test::Unit::TestCase
end
def test_cas
cache = Memcached.new(
@servers,
:namespace => @namespace,
:support_cas => true
)
value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
@cache.set key, @value
@cache.cas(key) do |current|
# Existing set
cache.set key, @value
cache.cas(key) do |current|
assert_equal @value, current
value2
end
assert_equal value2, @cache.get(key)
assert_equal value2, cache.get(key)
@cache.delete key
@cache.cas(key) do |current|
value2
end
assert_equal value2, @cache.get(key)
@cache.set key, @value
# Missing set
cache.delete key
assert_raises(Memcached::NotFound) do
@cache.cas(key) do |current|
@cache.set key, value2
cache.cas(key) {}
end
# Conflicting set
cache.set key, @value
# XXX Should raise Memcached::Exists
assert_raises(Memcached::UnknownReadFailure) do
cache.cas(key) do |current|
cache.set key, value2
current
end
end
cache.destroy
end
# Namespace and key validation