Permalink
Browse files

Memcache incrl/decrl for Long

  • Loading branch information...
1 parent 5071048 commit 1dbcd88bdecabfbae20a2d536f01e016ec243d2f @hjz hjz committed Mar 25, 2011
@@ -91,6 +91,20 @@ public static Client newInstance(Service<Command, Response> finagleClient) {
abstract public Future<Integer> decr(String key);
abstract public Future<Integer> decr(String key, int delta);
+ /**
+ * Increment a key. Interpret the key as an Long if it is parsable.
+ * This operation has no effect if there is no value there already.
+ */
+ abstract public Future<Long> incrl(String key);
+ abstract public Future<Long> incrl(String key, Long delta);
+
+ /**
+ * Decrement a key. Interpret the key as an Long if it is parsable.
+ * This operation has no effect if there is no value there already.
+ */
+ abstract public Future<Long> decrl(String key);
+ abstract public Future<Long> decrl(String key, Long delta);
+
public Future<Void> set(String key, String value) {
return this.set(key, toChannelBuffer(value));
}
@@ -110,4 +124,4 @@ public static Client newInstance(Service<Command, Response> finagleClient) {
private ChannelBuffer toChannelBuffer(String value) {
return ChannelBuffers.wrappedBuffer(value.getBytes());
}
-}
+}
@@ -120,4 +120,56 @@ public Integer apply(Option<Integer> value) {
}
});
}
-}
+
+ public Future<Long> incrl(String key) {
+ Future<Option<Long>> result = underlying.incrl(key);
+ return result.map(new Function<Option<Long>, Long>() {
+ public Long apply(Option<Long> value) {
+ if (value.isDefined()) {
+ return (Long) value.get();
+ } else {
+ return -1L;
+ }
+ }
+ });
+ }
+
+ public Future<Long> incrl(String key, Long delta) {
+ Future<Option<Long>> result = underlying.incrl(key, delta);
+ return result.map(new Function<Option<Long>, Long>() {
+ public Long apply(Option<Long> value) {
+ if (value.isDefined()) {
+ return (Long) value.get();
+ } else {
+ return -1L;
+ }
+ }
+ });
+ }
+
+ public Future<Long> decrl(String key) {
+ Future<Option<Long>> result = underlying.decrl(key);
+ return result.map(new Function<Option<Long>, Long>() {
+ public Long apply(Option<Long> value) {
+ if (value.isDefined()) {
+ return (Long) value.get();
+ } else {
+ return -1L;
+ }
+ }
+ });
+ }
+
+ public Future<Long> decrl(String key, Long delta) {
+ Future<Option<Long>> result = underlying.decrl(key, delta);
+ return result.map(new Function<Option<Long>, Long>() {
+ public Long apply(Option<Long> value) {
+ if (value.isDefined()) {
+ return (Long) value.get();
+ } else {
+ return -1L;
+ }
+ }
+ });
+ }
+}
@@ -103,6 +103,20 @@ trait Client {
def decr(key: String, delta: Int): Future[Option[Int]]
/**
+ * Increment a key. Interpret the key as an Long if it is parsable.
+ * This operation has no effect if there is no value there already.
+ */
+ def incrl(key: String): Future[Option[Long]]
+ def incrl(key: String, delta: Long): Future[Option[Long]]
+
+ /**
+ * Decrement a key. Interpret the key as an Long if it is parsable.
+ * This operation has no effect if there is no value there already.
+ */
+ def decrl(key: String): Future[Option[Long]]
+ def decrl(key: String, delta: Long): Future[Option[Long]]
+
+ /**
* Store a key. Override an existing values.
* @return true
*/
@@ -220,7 +234,17 @@ protected class ConnectedClient(service: Service[Command, Response]) extends Cli
def decr(key: String) = decr(key, 1)
- def incr(key: String, delta: Int): Future[Option[Int]] = {
+ def incr(key: String, delta: Int): Future[Option[Int]] =
+ incrl(key, delta) map { _ map (_.asInstanceOf[Int]) }
+
+ def decr(key: String, delta: Int): Future[Option[Int]] =
+ decrl(key, delta) map { _ map (_.asInstanceOf[Int]) }
+
+ def incrl(key: String) = incrl(key, 1L)
+
+ def decrl(key: String) = decrl(key, 1L)
+
+ def incrl(key: String, delta: Long): Future[Option[Long]] = {
service(Incr(key, delta)) map {
case Number(value) => Some(value)
case NotFound() => None
@@ -229,7 +253,7 @@ protected class ConnectedClient(service: Service[Command, Response]) extends Cli
}
}
- def decr(key: String, delta: Int): Future[Option[Int]] = {
+ def decrl(key: String, delta: Long): Future[Option[Long]] = {
service(Decr(key, delta)) map {
case Number(value) => Some(value)
case NotFound() => None
@@ -279,11 +303,15 @@ trait PartitionedClient extends Client {
def replace(key: String, flags: Int, expiry: Time, value: ChannelBuffer) =
clientOf(key).replace(key, flags, expiry, value)
- def delete(key: String) = clientOf(key).delete(key)
- def incr(key: String) = clientOf(key).incr(key)
- def incr(key: String, delta: Int) = clientOf(key).incr(key, delta)
- def decr(key: String) = clientOf(key).decr(key)
- def decr(key: String, delta: Int) = clientOf(key).decr(key, delta)
+ def delete(key: String) = clientOf(key).delete(key)
+ def incr(key: String) = clientOf(key).incr(key)
+ def incr(key: String, delta: Int) = clientOf(key).incr(key, delta)
+ def decr(key: String) = clientOf(key).decr(key)
+ def decr(key: String, delta: Int) = clientOf(key).decr(key, delta)
+ def incrl(key: String) = clientOf(key).incrl(key)
+ def incrl(key: String, delta: Long) = clientOf(key).incrl(key, delta)
+ def decrl(key: String) = clientOf(key).decrl(key)
+ def decrl(key: String, delta: Long) = clientOf(key).decrl(key, delta)
}
object PartitionedClient {
@@ -88,8 +88,8 @@ class Interpreter(map: AtomicMap[ChannelBuffer, ChannelBuffer]) {
throw new ClientError("cannot increment or decrement non-numeric value")
val existingValue =
- if (existingString.isEmpty) 0
- else existingString.toInt
+ if (existingString.isEmpty) 0L
+ else existingString.toLong
val result = existingValue + delta
data(key) = result.toString
@@ -7,7 +7,7 @@ sealed abstract class Command
abstract class StorageCommand(key: ChannelBuffer, flags: Int, expiry: Time, value: ChannelBuffer) extends Command
abstract class NonStorageCommand extends Command
-abstract class ArithmeticCommand(key: ChannelBuffer, delta: Int) extends NonStorageCommand
+abstract class ArithmeticCommand(key: ChannelBuffer, delta: Long) extends NonStorageCommand
abstract class RetrievalCommand(keys: Seq[ChannelBuffer]) extends NonStorageCommand
case class Set(key: ChannelBuffer, flags: Int, expiry: Time, value: ChannelBuffer) extends StorageCommand(key, flags, expiry, value)
@@ -20,5 +20,5 @@ case class Get(keys: Seq[ChannelBuffer])
case class Gets(keys: Seq[ChannelBuffer]) extends RetrievalCommand(keys)
case class Delete(key: ChannelBuffer) extends Command
-case class Incr(key: ChannelBuffer, value: Int) extends ArithmeticCommand(key, value)
-case class Decr(key: ChannelBuffer, value: Int) extends ArithmeticCommand(key, -value)
+case class Incr(key: ChannelBuffer, value: Long) extends ArithmeticCommand(key, value)
+case class Decr(key: ChannelBuffer, value: Long) extends ArithmeticCommand(key, -value)
@@ -10,6 +10,6 @@ case class Deleted() extends Response
case class Error(cause: Exception) extends Response
case class Values(values: Seq[Value]) extends Response
-case class Number(value: Int) extends Response
+case class Number(value: Long) extends Response
-case class Value(key: ChannelBuffer, value: ChannelBuffer)
+case class Value(key: ChannelBuffer, value: ChannelBuffer)
@@ -59,7 +59,7 @@ class DecodingToCommand extends AbstractDecodingToCommand[Command] {
if (tokens.size == 3 && tokens.last != NOREPLY) throw new ClientError("Too many arguments")
if (!tokens(1).matches(DIGITS)) throw new ClientError("Delta is not a number")
- (tokens.head, tokens(1).toInt)
+ (tokens.head, tokens(1).toLong)
}
protected def parseStorageCommand(tokens: Seq[ChannelBuffer], data: ChannelBuffer) = {
@@ -87,4 +87,4 @@ class DecodingToCommand extends AbstractDecodingToCommand[Command] {
case _ => throw new NonexistentCommand(commandName.toString)
}
}
-}
+}
@@ -18,6 +18,7 @@ private[finagle] object ChannelBufferUtils {
class RichChannelBuffer(buffer: ChannelBuffer) {
def matches(string: String) = buffer.toString(CharsetUtil.UTF_8).matches(string)
def toInt = toString.toInt
+ def toLong = toString.toLong
override def toString = buffer.toString(CharsetUtil.UTF_8)
def size = buffer.writerIndex() - buffer.readerIndex()

0 comments on commit 1dbcd88

Please sign in to comment.