Permalink
Browse files

Spymemcached integration and comparing configs functionality added.

Corresponding unit tests added.

Change-Id: I2a75636ccdffac243e87692806c17474b68e6df1
Reviewed-on: http://review.northscale.com/878
Reviewed-by: Dustin Sallings <dustin@spy.net>
Tested-by: Dustin Sallings <dustin@spy.net>
  • Loading branch information...
1 parent ce116e3 commit 63a8b107064768aef4b228387292c86b8f355c6c @eshelestovich eshelestovich committed with dustin Jun 24, 2010
View
@@ -71,23 +71,23 @@
<version>2.5.4</version>
<scope>test</scope>
</dependency>
- <!--
- <dependency>
- <groupId>org.springmodules</groupId>
- <artifactId>spring-modules-validation</artifactId>
- <version>0.9</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework</groupId>
- <artifactId>spring-mock</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- -->
+ <!--
+ <dependency>
+ <groupId>org.springmodules</groupId>
+ <artifactId>spring-modules-validation</artifactId>
+ <version>0.9</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-mock</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ -->
<!-- Commons dependencies -->
<dependency>
<groupId>commons-collections</groupId>
@@ -151,6 +151,11 @@
<artifactId>jettison</artifactId>
<version>1.2</version>
</dependency>
+ <dependency>
+ <groupId>spy</groupId>
+ <artifactId>memcached</artifactId>
+ <version>2.5</version>
+ </dependency>
</dependencies>
<build>
@@ -272,6 +277,10 @@
<targetJdk>1.5</targetJdk>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
</plugins>
</reporting>
@@ -285,6 +294,15 @@
<name>Maven Repository Switchboard</name>
<url>http://repo1.maven.org/maven2</url>
</repository>
+ <repository>
+ <id>spy</id>
+ <name>Spy Repository</name>
+ <layout>default</layout>
+ <url>http://bleu.west.spy.net/~dustin/m2repo/</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
</repositories>
</project>
@@ -9,8 +9,9 @@
package com.northscale.jvbucket;
-import com.northscale.jvbucket.model.HashAlgorithm;
+import com.northscale.jvbucket.model.ConfigDifference;
import com.northscale.jvbucket.model.VBucket;
+import net.spy.memcached.HashAlgorithm;
import java.util.List;
@@ -33,7 +34,7 @@
// VBucket access
- int getVbucketByKey(Object key, int nkey);
+ int getVbucketByKey(String key);
int getMaster(int vbucketIndex);
@@ -43,4 +44,9 @@
void setVbuckets(List<VBucket> vbuckets);
+ ConfigDifference compareTo(Config config);
+
+ List<String> getServers();
+
+ List<VBucket> getVbuckets();
}
@@ -9,11 +9,14 @@
package com.northscale.jvbucket;
-import com.northscale.jvbucket.model.HashAlgorithm;
+import com.northscale.jvbucket.model.ConfigDifference;
import com.northscale.jvbucket.model.VBucket;
+import net.spy.memcached.HashAlgorithm;
+import org.apache.commons.collections15.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -23,7 +26,7 @@
private final Log LOG = LogFactory.getLog(this.getClass());
- private HashAlgorithm hashAlgorithm = HashAlgorithm.DEFAULT;
+ private HashAlgorithm hashAlgorithm = HashAlgorithm.NATIVE_HASH;
private int vbucketsCount;
@@ -65,9 +68,8 @@ public String getServer(int serverIndex) {
return servers.get(serverIndex);
}
- public int getVbucketByKey(Object key, int nkey) {
- // TODO
- int digest = 0;
+ public int getVbucketByKey(String key) {
+ int digest = (int) hashAlgorithm.hash(key);
return digest & mask;
}
@@ -95,7 +97,52 @@ public void setVbuckets(List<VBucket> vbuckets) {
this.vbuckets = vbuckets;
}
+ public List<String> getServers() {
+ return servers;
+ }
+
+ public List<VBucket> getVbuckets() {
+ return vbuckets;
+ }
+
+ public ConfigDifference compareTo(Config config) {
+ ConfigDifference difference = new ConfigDifference();
+
+ // Compute the added and removed servers
+ difference.setServersAdded(new ArrayList<String>(CollectionUtils.subtract(config.getServers(), this.getServers())));
+ difference.setServersRemoved(new ArrayList<String>(CollectionUtils.subtract(this.getServers(), config.getServers())));
+
+ // Verify the servers are equal in their positions
+ if (this.serversCount == config.getServersCount()) {
+ difference.setSequenceChanged(false);
+ for (int i = 0; i < this.serversCount; i++) {
+ if (!this.getServer(i).equals(config.getServer(i))) {
+ difference.setSequenceChanged(true);
+ break;
+ }
+ }
+ } else {
+ // Just say yes
+ difference.setSequenceChanged(true);
+ }
+
+ // Count the number of vbucket differences
+ if (this.vbucketsCount == config.getVbucketsCount()) {
+ int vbucketsChanges = 0;
+ for (int i = 0; i < this.vbucketsCount; i++) {
+ vbucketsChanges += (this.getMaster(i) == config.getMaster(i)) ? 0 : 1;
+ }
+ difference.setVbucketsChanges(vbucketsChanges);
+ } else {
+ difference.setVbucketsChanges(-1);
+ }
+
+ return difference;
+ }
+
public HashAlgorithm getHashAlgorithm() {
return hashAlgorithm;
}
+
+
}
@@ -10,8 +10,8 @@
package com.northscale.jvbucket;
import com.northscale.jvbucket.exception.ConfigParsingException;
-import com.northscale.jvbucket.model.HashAlgorithm;
import com.northscale.jvbucket.model.VBucket;
+import net.spy.memcached.HashAlgorithm;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -60,12 +60,30 @@ public Config createConfigFromString(String data) {
}
}
+ private HashAlgorithm lookupHashAlgorithm(String algorithm) {
+ HashAlgorithm ha = HashAlgorithm.NATIVE_HASH;
+ if ("crc".equalsIgnoreCase(algorithm)) {
+ ha = HashAlgorithm.CRC32_HASH;
+ } else if ("fnv1_32".equalsIgnoreCase(algorithm)) {
+ ha = HashAlgorithm.FNV1_32_HASH;
+ } else if ("fnv1_64".equalsIgnoreCase(algorithm)) {
+ ha = HashAlgorithm.FNV1_64_HASH;
+ } else if ("fnv1a_32".equalsIgnoreCase(algorithm)) {
+ ha = HashAlgorithm.FNV1A_32_HASH;
+ } else if ("fnv1a_64".equalsIgnoreCase(algorithm)) {
+ ha = HashAlgorithm.FNV1A_64_HASH;
+ } else if ("md5".equalsIgnoreCase(algorithm)) {
+ ha = HashAlgorithm.KETAMA_HASH;
+ }
+ return ha;
+ }
+
private Config parseJSON(JSONObject jsonObject) throws JSONException {
// Allows clients to have a JSON envelope.
if (jsonObject.has("vBucketServerMap")) {
return parseJSON(jsonObject.getJSONObject("vBucketServerMap"));
}
- HashAlgorithm hashAlgorithm = HashAlgorithm.parse(jsonObject.getString("hashAlgorithm"));
+ HashAlgorithm hashAlgorithm = lookupHashAlgorithm(jsonObject.getString("hashAlgorithm"));
int replicasCount = jsonObject.getInt("numReplicas");
if (replicasCount > VBucket.MAX_REPLICAS) {
throw new ConfigParsingException("Expected number <= " + VBucket.MAX_REPLICAS + " for replicas.");
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009, NorthScale, Inc.
+ *
+ * All rights reserved.
+ *
+ * info@northscale.com
+ *
+ */
+
+package com.northscale.jvbucket.model;
+
+import java.util.List;
+
+/**
+ * @author Eugene Shelestovich
+ */
+public class ConfigDifference {
+
+ /**
+ * List of server names that were added.
+ */
+ private List<String> serversAdded;
+
+ /**
+ * List of server names that were removed.
+ */
+ private List<String> serversRemoved;
+
+ /**
+ * Number of vbuckets that changed. -1 if the total number changed.
+ */
+ private int vbucketsChanges;
+
+ /**
+ * True if the sequence of servers changed.
+ */
+ private boolean sequenceChanged;
+
+ public List<String> getServersAdded() {
+ return serversAdded;
+ }
+
+ public void setServersAdded(List<String> serversAdded) {
+ this.serversAdded = serversAdded;
+ }
+
+ public List<String> getServersRemoved() {
+ return serversRemoved;
+ }
+
+ public void setServersRemoved(List<String> serversRemoved) {
+ this.serversRemoved = serversRemoved;
+ }
+
+ public int getVbucketsChanges() {
+ return vbucketsChanges;
+ }
+
+ public void setVbucketsChanges(int vbucketsChanges) {
+ this.vbucketsChanges = vbucketsChanges;
+ }
+
+ public boolean isSequenceChanged() {
+ return sequenceChanged;
+ }
+
+ public void setSequenceChanged(boolean sequenceChanged) {
+ this.sequenceChanged = sequenceChanged;
+ }
+}
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2009, NorthScale, Inc.
- *
- * All rights reserved.
- *
- * info@northscale.com
- *
- */
-
-package com.northscale.jvbucket.model;
-
-/**
- * @author Eugene Shelestovich
- */
-public enum HashAlgorithm {
-
- DEFAULT("default"),
- MD5("md5"),
- CRC("crc"),
- FNV1_64("fnv1_64"),
- FNV1A_64("fnv1a_64"),
- FNV1_32("fnv1_32"),
- FNV1A_32("fnv1a_32"),
- HSIEH("hsieh"),
- MURMUR("murmur"),
- JENKINS("jenkins");
-
- private String value;
-
- HashAlgorithm(String value) {
- this.value = value;
- }
-
- public String getValue() {
- return value;
- }
-
- public static HashAlgorithm parse(String hashAlgorithm) {
- for (HashAlgorithm algorithm : HashAlgorithm.values()) {
- if (algorithm.getValue().equalsIgnoreCase(hashAlgorithm)) {
- return algorithm;
- }
- }
- return DEFAULT;
- }
-
- @Override
- public String toString() {
- return value;
- }
-}
Oops, something went wrong.

0 comments on commit 63a8b10

Please sign in to comment.