Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #4 from robrasmussen/master

Implement missing memcached methods
  • Loading branch information...
commit 4a4f759709b930f44cd7ff6c2e33eb71f5afeb97 2 parents 07dd85c + 399c075
@headius authored
View
5 .gitignore
@@ -1,2 +1,5 @@
/.redcar/
-/target/
+.idea/
+*.iml
+/target/
+/out/
View
170 src/main/java/com/headius/spymemcached/SpymemcachedLibrary.java
@@ -4,6 +4,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -18,6 +19,8 @@
import org.jruby.RubyClass;
import org.jruby.RubyHash;
import org.jruby.RubyObject;
+import org.jruby.RubyString;
+import org.jruby.RubySymbol;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
@@ -50,6 +53,10 @@ public IRubyObject allocate(Ruby ruby, RubyClass rc) {
getFutureClass = spymemcached.defineClassUnder("GetFuture", ruby.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
bulkFutureClass = spymemcached.defineClassUnder("BulkFuture", ruby.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
+ operationFutureClass.defineAnnotatedMethods(_OperationFuture.class);
+ getFutureClass.defineAnnotatedMethods(_GetFuture.class);
+ bulkFutureClass.defineAnnotatedMethods(_BulkFuture.class);
+
transcoder = new Transcoder<IRubyObject>() {
static final int STRING = 0;
@@ -85,13 +92,18 @@ public int getMaxSize() {
public class Spymemcached extends RubyObject {
private MemcachedClient client;
+ private NamespaceHelper namespaceHelper;
public Spymemcached(final Ruby ruby, RubyClass rubyClass) {
super(ruby, rubyClass);
}
-
+
@JRubyMethod
public IRubyObject initialize(ThreadContext context, IRubyObject servers) {
+ return initialize(context, servers, context.nil);
+ }
+ @JRubyMethod
+ public IRubyObject initialize(ThreadContext context, IRubyObject servers, IRubyObject options) {
ArrayList<InetSocketAddress> serverSocks = new ArrayList();
for (String server : (List<String>)servers.convertToArray()) {
@@ -105,13 +117,29 @@ public IRubyObject initialize(ThreadContext context, IRubyObject servers) {
throw context.runtime.newIOErrorFromException(ioe);
}
+ String namespace = null;
+ if (options != context.nil) {
+ RubyHash optionsHash = options.convertToHash();
+ RubySymbol namespaceSymbol = RubySymbol.newSymbol(context.getRuntime(), "namespace");
+ if (optionsHash.containsKey(namespaceSymbol)) {
+ namespace = optionsHash.get(namespaceSymbol).toString();
+ }
+ }
+
+ this.namespaceHelper = new NamespaceHelper(namespace);
+
return context.nil;
}
-
+
@JRubyMethod
- public IRubyObject set(ThreadContext context, IRubyObject key, IRubyObject value) {
+ public IRubyObject add(ThreadContext context, IRubyObject key, IRubyObject value) {
+ return add(context, key, value, ruby.newFixnum(0));
+ }
+
+ @JRubyMethod
+ public IRubyObject add(ThreadContext context, IRubyObject key, IRubyObject value, IRubyObject timeout) {
try {
- return ruby.newBoolean(client.set(key.toString(), 0, value, transcoder).get());
+ return ruby.newBoolean(client.add(namespaceHelper.namespacedKey(key), (int)timeout.convertToInteger().getLongValue(), value, transcoder).get());
} catch (ExecutionException ee) {
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
} catch (InterruptedException ie) {
@@ -120,9 +148,14 @@ public IRubyObject set(ThreadContext context, IRubyObject key, IRubyObject value
}
@JRubyMethod
+ public IRubyObject set(ThreadContext context, IRubyObject key, IRubyObject value) {
+ return set(context, key, value, ruby.newFixnum(0));
+ }
+
+ @JRubyMethod
public IRubyObject set(ThreadContext context, IRubyObject key, IRubyObject value, IRubyObject timeout) {
try {
- return ruby.newBoolean(client.set(key.toString(), (int)timeout.convertToInteger().getLongValue(), value, transcoder).get());
+ return ruby.newBoolean(client.set(namespaceHelper.namespacedKey(key), (int)timeout.convertToInteger().getLongValue(), value, transcoder).get());
} catch (ExecutionException ee) {
throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
} catch (InterruptedException ie) {
@@ -132,42 +165,104 @@ public IRubyObject set(ThreadContext context, IRubyObject key, IRubyObject value
@JRubyMethod
public IRubyObject async_set(ThreadContext context, IRubyObject key, IRubyObject value) {
- return new _OperationFuture(client.set(key.toString(), 0, value, transcoder));
+ return new _OperationFuture(client.set(namespaceHelper.namespacedKey(key), 0, value, transcoder));
}
@JRubyMethod
public IRubyObject async_set(ThreadContext context, IRubyObject key, IRubyObject value, IRubyObject timeout) {
- return new _OperationFuture(client.set(key.toString(), (int)timeout.convertToInteger().getLongValue(), value, transcoder));
+ return new _OperationFuture(client.set(namespaceHelper.namespacedKey(key), (int)timeout.convertToInteger().getLongValue(), value, transcoder));
}
@JRubyMethod
public IRubyObject get(ThreadContext context, IRubyObject key) {
- try {
- return client.asyncGet(key.toString(), transcoder).get();
- } catch (ExecutionException ee) {
- throw ruby.newThreadError(ee.getLocalizedMessage());
- } catch (InterruptedException ie) {
- throw ruby.newThreadError(ie.getLocalizedMessage());
- }
+ return client.get(namespaceHelper.namespacedKey(key), transcoder);
}
@JRubyMethod
public IRubyObject multiget(ThreadContext context, IRubyObject keys) {
RubyHash results = RubyHash.newHash(ruby);
- for (Map.Entry<String, IRubyObject> entry : client.getBulk((List<String>)keys.convertToArray(), transcoder).entrySet()) {
- results.op_aset(context, ruby.newString(entry.getKey()), entry.getValue());
+
+ for (Map.Entry<String, IRubyObject> entry : client.getBulk(namespaceHelper.namespacedKeys(keys), transcoder).entrySet()) {
+ results.op_aset(context, namespaceHelper.unnamespacedKey(entry.getKey()), entry.getValue());
}
return results;
}
-
+
@JRubyMethod
public IRubyObject async_get(ThreadContext context, IRubyObject key) {
- return new _GetFuture(client.asyncGet(key.toString(), transcoder));
+ return new _GetFuture(client.asyncGet(namespaceHelper.namespacedKey(key), transcoder));
}
-
+
@JRubyMethod
public IRubyObject async_multiget(ThreadContext context, IRubyObject keys) {
- return new _BulkFuture(client.asyncGetBulk((List<String>)keys.convertToArray(), transcoder));
+ return new _BulkFuture(client.asyncGetBulk(namespaceHelper.namespacedKeys(keys), transcoder), namespaceHelper);
+ }
+
+ @JRubyMethod
+ public IRubyObject incr(ThreadContext context, IRubyObject key) {
+ return incr(context, key, ruby.newFixnum(1), ruby.newFixnum(0));
+ }
+
+ @JRubyMethod
+ public IRubyObject incr(ThreadContext context, IRubyObject key, IRubyObject by) {
+ return incr(context, key, by, ruby.newFixnum(0));
+ }
+
+ @JRubyMethod
+ public IRubyObject incr(ThreadContext context, IRubyObject key, IRubyObject by, IRubyObject timeout) {
+ long result = client.incr(namespaceHelper.namespacedKey(key), (int)by.convertToInteger().getLongValue(), 1, (int)timeout.convertToInteger().getLongValue());
+ return ruby.newFixnum(result);
+ }
+
+ @JRubyMethod
+ public IRubyObject decr(ThreadContext context, IRubyObject key) {
+ return decr(context, key, ruby.newFixnum(1), ruby.newFixnum(0));
+ }
+
+ @JRubyMethod
+ public IRubyObject decr(ThreadContext context, IRubyObject key, IRubyObject by) {
+ return decr(context, key, by, ruby.newFixnum(0));
+ }
+
+ @JRubyMethod
+ public IRubyObject decr(ThreadContext context, IRubyObject key, IRubyObject by, IRubyObject timeout) {
+ long result = client.decr(namespaceHelper.namespacedKey(key), (int)by.convertToInteger().getLongValue(), 0, (int)timeout.convertToInteger().getLongValue());
+ return ruby.newFixnum(result);
+ }
+
+ @JRubyMethod
+ public IRubyObject delete(ThreadContext context, IRubyObject key) {
+ try {
+ return ruby.newBoolean(client.delete(namespaceHelper.namespacedKey(key)).get());
+ } catch (ExecutionException ee) {
+ throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
+ } catch (InterruptedException ie) {
+ throw context.runtime.newThreadError(ie.getLocalizedMessage());
+ }
+ }
+
+ @JRubyMethod
+ public IRubyObject clear(ThreadContext context) {
+ try {
+ return ruby.newBoolean(client.flush().get());
+ } catch (ExecutionException ee) {
+ throw context.runtime.newRuntimeError(ee.getLocalizedMessage());
+ } catch (InterruptedException ie) {
+ throw context.runtime.newThreadError(ie.getLocalizedMessage());
+ }
+ }
+
+ @JRubyMethod
+ public IRubyObject stats(ThreadContext context) {
+ RubyHash results = RubyHash.newHash(ruby);
+ for(Map.Entry<SocketAddress, Map<String, String>> entry : client.getStats().entrySet()) {
+ RubyHash serverHash = RubyHash.newHash(ruby);
+ for(Map.Entry<String, String> server : entry.getValue().entrySet()) {
+ serverHash.op_aset(context, ruby.newString(server.getKey()), ruby.newString(server.getValue()));
+ }
+ results.op_aset(context, ruby.newString(entry.getKey().toString()), serverHash);
+ }
+ return results;
}
@JRubyMethod
@@ -187,7 +282,7 @@ public _OperationFuture(OperationFuture<Boolean> response) {
}
@JRubyMethod
- public IRubyObject get() {
+ public IRubyObject get(ThreadContext context) {
try {
return ruby.newBoolean(future.get());
} catch (ExecutionException ee) {
@@ -207,7 +302,7 @@ public _GetFuture(GetFuture<IRubyObject> future) {
}
@JRubyMethod
- public IRubyObject get() {
+ public IRubyObject get(ThreadContext context) {
try {
return future.get();
} catch (ExecutionException ee) {
@@ -220,10 +315,12 @@ public IRubyObject get() {
public class _BulkFuture extends RubyObject {
private BulkFuture<Map<String, IRubyObject>> bulkFuture;
-
- public _BulkFuture(BulkFuture<Map<String, IRubyObject>> bulkFuture) {
+ private NamespaceHelper namespaceHelper;
+
+ public _BulkFuture(BulkFuture<Map<String, IRubyObject>> bulkFuture, NamespaceHelper helper) {
super(ruby, bulkFutureClass);
this.bulkFuture = bulkFuture;
+ this.namespaceHelper = helper;
}
@JRubyMethod
@@ -231,7 +328,7 @@ public IRubyObject get(ThreadContext context) {
try {
RubyHash results = RubyHash.newHash(ruby);
for (Map.Entry<String, IRubyObject> entry : bulkFuture.get().entrySet()) {
- results.op_aset(context, ruby.newString(entry.getKey()), entry.getValue());
+ results.op_aset(context, this.namespaceHelper.unnamespacedKey(entry.getKey()), entry.getValue());
}
return results;
} catch (ExecutionException ee) {
@@ -241,4 +338,27 @@ public IRubyObject get(ThreadContext context) {
}
}
}
+
+ public class NamespaceHelper {
+ private String namespace;
+ public NamespaceHelper(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public String namespacedKey(IRubyObject key) {
+ return namespace != null ? namespace + key.toString() : key.toString();
+ }
+
+ public List<String> namespacedKeys(IRubyObject keys) {
+ List<String> results = new ArrayList<String>();
+ for(String key : (List<String>)keys.convertToArray()) {
+ results.add(namespace == null ? key : namespace + key);
+ }
+ return results;
+ }
+
+ public IRubyObject unnamespacedKey(String key) {
+ return namespace != null ? ruby.newString(key.substring(namespace.length())) : ruby.newString(key);
+ }
+ }
}
Please sign in to comment.
Something went wrong with that request. Please try again.