Skip to content

Commit 6ada2e6

Browse files
daschlMichael Nitschinger
authored andcommitted
SPY-156: Expose more async mutate methods.
Motivation ---------- More flexible incr/decr methods are exposed as sync variants than with their async counterparts. This patch is an effort to bring them on par (almost) completely. Modifications ------------- More async variants have been exposed, which were already supported through the private asyncMutate method. Note that since the ascii protocol doesn't support defaults and expiration for incr/decr, those return an UnsupportedOperationException, because it is nontrivial to fix. Please refer to the sync variants if you need that. Result ------ When the binary protocol is used, much more asyncIncr/asyncDecr methods are exposed, explicitly helping with default values and expiration. Change-Id: I4403b14d6146afb325afa9c239da28b55e89e935 Reviewed-on: http://review.couchbase.org/34257 Reviewed-by: Michael Nitschinger <michael.nitschinger@couchbase.com> Tested-by: Michael Nitschinger <michael.nitschinger@couchbase.com>
1 parent e6892a0 commit 6ada2e6

4 files changed

Lines changed: 203 additions & 10 deletions

File tree

src/main/java/net/spy/memcached/MemcachedClient.java

Lines changed: 141 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
import net.spy.memcached.ops.StoreOperation;
7575
import net.spy.memcached.ops.StoreType;
7676
import net.spy.memcached.ops.TimedOutOperationStatus;
77+
import net.spy.memcached.protocol.ascii.AsciiOperationFactory;
7778
import net.spy.memcached.protocol.binary.BinaryOperationFactory;
7879
import net.spy.memcached.transcoders.TranscodeService;
7980
import net.spy.memcached.transcoders.Transcoder;
@@ -1978,6 +1979,12 @@ private long mutateWithDefault(Mutator t, String key, long by, long def,
19781979

19791980
private OperationFuture<Long> asyncMutate(Mutator m, String key, long by,
19801981
long def, int exp) {
1982+
if (!(opFact instanceof BinaryOperationFactory) && (def != 0 || exp != -1)) {
1983+
throw new UnsupportedOperationException("Default value or expiration "
1984+
+ "time are not supported on the async mutate methods. Use either the "
1985+
+ "binary protocol or the sync variant.");
1986+
}
1987+
19811988
final CountDownLatch latch = new CountDownLatch(1);
19821989
final OperationFuture<Long> rv =
19831990
new OperationFuture<Long>(key, latch, operationTimeout, executorService);
@@ -2030,9 +2037,9 @@ public OperationFuture<Long> asyncIncr(String key, int by) {
20302037
/**
20312038
* Asynchronous decrement.
20322039
*
2033-
* @param key key to increment
2034-
* @param by the amount to increment the value by
2035-
* @return a future with the decremented value, or -1 if the increment failed.
2040+
* @param key key to decrement
2041+
* @param by the amount to decrement the value by
2042+
* @return a future with the decremented value, or -1 if the decrement failed.
20362043
* @throws IllegalStateException in the rare circumstance where queue is too
20372044
* full to accept any more requests
20382045
*/
@@ -2044,9 +2051,9 @@ public OperationFuture<Long> asyncDecr(String key, long by) {
20442051
/**
20452052
* Asynchronous decrement.
20462053
*
2047-
* @param key key to increment
2048-
* @param by the amount to increment the value by
2049-
* @return a future with the decremented value, or -1 if the increment failed.
2054+
* @param key key to decrement
2055+
* @param by the amount to decrement the value by
2056+
* @return a future with the decremented value, or -1 if the decrement failed.
20502057
* @throws IllegalStateException in the rare circumstance where queue is too
20512058
* full to accept any more requests
20522059
*/
@@ -2055,6 +2062,134 @@ public OperationFuture<Long> asyncDecr(String key, int by) {
20552062
return asyncMutate(Mutator.decr, key, by, 0, -1);
20562063
}
20572064

2065+
/**
2066+
* Asychronous increment.
2067+
*
2068+
* @param key key to increment
2069+
* @param by the amount to increment the value by
2070+
* @param def the default value (if the counter does not exist)
2071+
* @param exp the expiration of this object
2072+
* @return a future with the incremented value, or -1 if the increment failed.
2073+
* @throws IllegalStateException in the rare circumstance where queue is too
2074+
* full to accept any more requests
2075+
*/
2076+
@Override
2077+
public OperationFuture<Long> asyncIncr(String key, long by, long def,
2078+
int exp) {
2079+
return asyncMutate(Mutator.incr, key, by, def, exp);
2080+
}
2081+
2082+
/**
2083+
* Asychronous increment.
2084+
*
2085+
* @param key key to increment
2086+
* @param by the amount to increment the value by
2087+
* @param def the default value (if the counter does not exist)
2088+
* @param exp the expiration of this object
2089+
* @return a future with the incremented value, or -1 if the increment failed.
2090+
* @throws IllegalStateException in the rare circumstance where queue is too
2091+
* full to accept any more requests
2092+
*/
2093+
@Override
2094+
public OperationFuture<Long> asyncIncr(String key, int by, long def,
2095+
int exp) {
2096+
return asyncMutate(Mutator.incr, key, by, def, exp);
2097+
}
2098+
2099+
/**
2100+
* Asynchronous decrement.
2101+
*
2102+
* @param key key to decrement
2103+
* @param by the amount to decrement the value by
2104+
* @param def the default value (if the counter does not exist)
2105+
* @param exp the expiration of this object
2106+
* @return a future with the decremented value, or -1 if the decrement failed.
2107+
* @throws IllegalStateException in the rare circumstance where queue is too
2108+
* full to accept any more requests
2109+
*/
2110+
@Override
2111+
public OperationFuture<Long> asyncDecr(String key, long by, long def,
2112+
int exp) {
2113+
return asyncMutate(Mutator.decr, key, by, def, exp);
2114+
}
2115+
2116+
/**
2117+
* Asynchronous decrement.
2118+
*
2119+
* @param key key to decrement
2120+
* @param by the amount to decrement the value by
2121+
* @param def the default value (if the counter does not exist)
2122+
* @param exp the expiration of this object
2123+
* @return a future with the decremented value, or -1 if the decrement failed.
2124+
* @throws IllegalStateException in the rare circumstance where queue is too
2125+
* full to accept any more requests
2126+
*/
2127+
@Override
2128+
public OperationFuture<Long> asyncDecr(String key, int by, long def,
2129+
int exp) {
2130+
return asyncMutate(Mutator.decr, key, by, def, exp);
2131+
}
2132+
2133+
/**
2134+
* Asychronous increment.
2135+
*
2136+
* @param key key to increment
2137+
* @param by the amount to increment the value by
2138+
* @param def the default value (if the counter does not exist)
2139+
* @return a future with the incremented value, or -1 if the increment failed.
2140+
* @throws IllegalStateException in the rare circumstance where queue is too
2141+
* full to accept any more requests
2142+
*/
2143+
@Override
2144+
public OperationFuture<Long> asyncIncr(String key, long by, long def) {
2145+
return asyncMutate(Mutator.incr, key, by, def, 0);
2146+
}
2147+
2148+
/**
2149+
* Asychronous increment.
2150+
*
2151+
* @param key key to increment
2152+
* @param by the amount to increment the value by
2153+
* @param def the default value (if the counter does not exist)
2154+
* @return a future with the incremented value, or -1 if the increment failed.
2155+
* @throws IllegalStateException in the rare circumstance where queue is too
2156+
* full to accept any more requests
2157+
*/
2158+
@Override
2159+
public OperationFuture<Long> asyncIncr(String key, int by, long def) {
2160+
return asyncMutate(Mutator.incr, key, by, def, 0);
2161+
}
2162+
2163+
/**
2164+
* Asynchronous decrement.
2165+
*
2166+
* @param key key to decrement
2167+
* @param by the amount to decrement the value by
2168+
* @param def the default value (if the counter does not exist)
2169+
* @return a future with the decremented value, or -1 if the decrement failed.
2170+
* @throws IllegalStateException in the rare circumstance where queue is too
2171+
* full to accept any more requests
2172+
*/
2173+
@Override
2174+
public OperationFuture<Long> asyncDecr(String key, long by, long def) {
2175+
return asyncMutate(Mutator.decr, key, by, def, 0);
2176+
}
2177+
2178+
/**
2179+
* Asynchronous decrement.
2180+
*
2181+
* @param key key to decrement
2182+
* @param by the amount to decrement the value by
2183+
* @param def the default value (if the counter does not exist)
2184+
* @return a future with the decremented value, or -1 if the decrement failed.
2185+
* @throws IllegalStateException in the rare circumstance where queue is too
2186+
* full to accept any more requests
2187+
*/
2188+
@Override
2189+
public OperationFuture<Long> asyncDecr(String key, int by, long def) {
2190+
return asyncMutate(Mutator.decr, key, by, def, 0);
2191+
}
2192+
20582193
/**
20592194
* Increment the given counter, returning the new value.
20602195
*

src/main/java/net/spy/memcached/MemcachedClientIF.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ <T> Future<Boolean> touch(final String key, final int exp,
172172

173173
long decr(String key, int by);
174174

175+
Future<Long> asyncIncr(String key, long by);
176+
177+
Future<Long> asyncIncr(String key, int by);
178+
179+
Future<Long> asyncDecr(String key, long by);
180+
181+
Future<Long> asyncDecr(String key, int by);
182+
175183
long incr(String key, long by, long def, int exp);
176184

177185
long incr(String key, int by, long def, int exp);
@@ -180,13 +188,13 @@ <T> Future<Boolean> touch(final String key, final int exp,
180188

181189
long decr(String key, int by, long def, int exp);
182190

183-
Future<Long> asyncIncr(String key, long by);
191+
Future<Long> asyncIncr(String key, long by, long def, int exp);
184192

185-
Future<Long> asyncIncr(String key, int by);
193+
Future<Long> asyncIncr(String key, int by, long def, int exp);
186194

187-
Future<Long> asyncDecr(String key, long by);
195+
Future<Long> asyncDecr(String key, long by, long def, int exp);
188196

189-
Future<Long> asyncDecr(String key, int by);
197+
Future<Long> asyncDecr(String key, int by, long def, int exp);
190198

191199
long incr(String key, long by, long def);
192200

@@ -196,6 +204,14 @@ <T> Future<Boolean> touch(final String key, final int exp,
196204

197205
long decr(String key, int by, long def);
198206

207+
Future<Long> asyncIncr(String key, long by, long def);
208+
209+
Future<Long> asyncIncr(String key, int by, long def);
210+
211+
Future<Long> asyncDecr(String key, long by, long def);
212+
213+
Future<Long> asyncDecr(String key, int by, long def);
214+
199215
Future<Boolean> delete(String key);
200216

201217
Future<Boolean> delete(String key, long cas);

src/test/java/net/spy/memcached/AsciiClientTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,24 @@ public void testAddGetSetStatusCodes() throws Exception {
105105
assertEquals(StatusCode.ERR_NOT_STORED, add.getStatus().getStatusCode());
106106
}
107107

108+
public void testAsyncIncrementWithDefault() throws Exception {
109+
String k = "async-incr-with-default";
110+
try {
111+
client.asyncIncr(k, 1, 5);
112+
assertTrue(false);
113+
} catch (UnsupportedOperationException e) {
114+
assertTrue(true);
115+
}
116+
}
117+
118+
public void testAsyncDecrementWithDefault() throws Exception {
119+
String k = "async-decr-with-default";
120+
try {
121+
client.asyncDecr(k, 1, 5);
122+
assertTrue(false);
123+
} catch (UnsupportedOperationException e) {
124+
assertTrue(true);
125+
}
126+
}
127+
108128
}

src/test/java/net/spy/memcached/BinaryClientTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,4 +199,26 @@ public void testAddGetSetStatusCodes() throws Exception {
199199
assertEquals(StatusCode.ERR_EXISTS, add.getStatus().getStatusCode());
200200
}
201201

202+
public void testAsyncIncrementWithDefault() throws Exception {
203+
String k = "async-incr-with-default";
204+
OperationFuture<Long> f = client.asyncIncr(k, 1, 5);
205+
assertEquals(StatusCode.SUCCESS, f.getStatus().getStatusCode());
206+
assertEquals(5, (long) f.get());
207+
208+
f = client.asyncIncr(k, 1, 5);
209+
assertEquals(StatusCode.SUCCESS, f.getStatus().getStatusCode());
210+
assertEquals(6, (long) f.get());
211+
}
212+
213+
public void testAsyncDecrementWithDefault() throws Exception {
214+
String k = "async-decr-with-default";
215+
OperationFuture<Long> f = client.asyncDecr(k, 4, 10);
216+
assertEquals(StatusCode.SUCCESS, f.getStatus().getStatusCode());
217+
assertEquals(10, (long) f.get());
218+
219+
f = client.asyncDecr(k, 4, 10);
220+
assertEquals(StatusCode.SUCCESS, f.getStatus().getStatusCode());
221+
assertEquals(6, (long) f.get());
222+
}
223+
202224
}

0 commit comments

Comments
 (0)