Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: twitter/finagle
...
head fork: twitter/finagle
Checking mergeability… Don't worry, you can still create the pull request.
  • 3 commits
  • 12 files changed
  • 0 commit comments
  • 1 contributor
View
16 finagle-memcached/src/main/java/com/twitter/finagle/memcached/java/Client.java
@@ -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());
}
-}
+}
View
54 finagle-memcached/src/main/java/com/twitter/finagle/memcached/java/ClientBase.java
@@ -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;
+ }
+ }
+ });
+ }
+}
View
42 finagle-memcached/src/main/scala/com/twitter/finagle/memcached/Client.scala
@@ -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 {
View
4 finagle-memcached/src/main/scala/com/twitter/finagle/memcached/Interpreter.scala
@@ -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
View
6 finagle-memcached/src/main/scala/com/twitter/finagle/memcached/protocol/Command.scala
@@ -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)
View
4 finagle-memcached/src/main/scala/com/twitter/finagle/memcached/protocol/Response.scala
@@ -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)
View
2  finagle-memcached/src/main/scala/com/twitter/finagle/memcached/protocol/text/client/Decoder.scala
@@ -89,4 +89,4 @@ class Decoder extends AbstractDecoder with StateMachine {
if (args.length == 4 && !args(3).matches(DIGITS)) throw new ServerError("CAS must be a number")
if (!args(2).matches(DIGITS)) throw new ServerError("Bytes must be number")
}
-}
+}
View
4 ...gle-memcached/src/main/scala/com/twitter/finagle/memcached/protocol/text/client/DecodingToResponse.scala
@@ -42,7 +42,7 @@ class DecodingToResponse extends AbstractDecodingToResponse[Response] {
case ERROR => Error(new NonexistentCommand(""))
case CLIENT_ERROR => Error(new ClientError(""))
case SERVER_ERROR => Error(new ServerError(""))
- case ds => Number(ds.toInt)
+ case ds => Number(ds.toLong)
}
}
@@ -54,4 +54,4 @@ class DecodingToResponse extends AbstractDecodingToResponse[Response] {
}
Values(values)
}
-}
+}
View
3  finagle-memcached/src/main/scala/com/twitter/finagle/memcached/protocol/text/server/Decoder.scala
@@ -57,5 +57,4 @@ class Decoder(storageCommands: collection.Set[ChannelBuffer]) extends AbstractDe
if (tokens.size > 5) throw new ClientError("Too many arguments")
if (!tokens(3).matches(DIGITS)) throw new ClientError("Bad frame length")
}
-
-}
+}
View
4 finagle-memcached/src/main/scala/com/twitter/finagle/memcached/protocol/text/server/DecodingToCommand.scala
@@ -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)
}
}
-}
+}
View
1  finagle-memcached/src/main/scala/com/twitter/finagle/memcached/util/ChannelBufferUtils.scala
@@ -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()
View
9 finagle-memcached/src/test/scala/com/twitter/finagle/memcached/integration/ClientSpec.scala
@@ -64,6 +64,15 @@ object ClientSpec extends Specification {
client.incr("foo", 2)() mustEqual Some(3)
client.decr("foo")() mustEqual Some(2)
}
+
+ "incrl & decrl" in {
+ client.set("foo", "")()
+ client.incrl("foo")() mustEqual Some(1L)
+ val l = 1L << 50
+ client.incrl("foo", l)() mustEqual Some(l + 1L)
+ client.decrl("foo")() mustEqual Some(l)
+ client.decrl("foo", l)() mustEqual Some(0L)
+ }
}
"ketama client" in {

No commit comments for this range

Something went wrong with that request. Please try again.