-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use HashTreeSet to manage expiration. refactor command processor.
- Loading branch information
Showing
5 changed files
with
165 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package com.kenlai.MKLRedis; | ||
|
||
import java.util.regex.Pattern; | ||
|
||
public class CommandProcessor { | ||
private boolean verbose = Boolean.getBoolean("verbose"); | ||
private int initialSize = Integer.getInteger("initialSize", 16); | ||
|
||
private final static Pattern validatorPattern = | ||
Pattern.compile("\\A[ a-zA-Z0-9-_]*\\z"); | ||
|
||
private CachingStore store = new CachingStore(initialSize); | ||
|
||
/** | ||
* Parses the full command string and forwards to appropriate method. | ||
* | ||
* @return result value of the command | ||
*/ | ||
public String process(String fullCmd) { | ||
if (!validatorPattern.matcher(fullCmd).matches()) { | ||
verbosePrintln("invalid input characters detected"); | ||
return "ERROR invalid input characters detected"; | ||
} | ||
String[] tokens = fullCmd.split(" "); | ||
try { | ||
Command cmd = Command.valueOf(tokens[0]); | ||
switch (cmd) { | ||
case SET: | ||
Long expiration = null; | ||
if (tokens.length == 5 && tokens[3].equals("EX")) { | ||
expiration = Long.getLong(tokens[4]); | ||
} else if (tokens.length != 3) { | ||
verbosePrintln("incorrect parameters for SET"); | ||
return "ERROR bad SET parameters"; | ||
} | ||
return store.set(tokens[1], tokens[2], expiration); | ||
case GET: | ||
verifyLength(tokens, 2); | ||
return store.get(tokens[1]); | ||
case INCR: | ||
verifyLength(tokens, 2); | ||
return store.incr(tokens[1]).toString(); | ||
case DEL: | ||
verifyLength(tokens, 2); | ||
return Integer.toString(store.del(tokens[1])); | ||
case DBSIZE: | ||
verifyLength(tokens, 1); | ||
return Integer.toString(store.dbsize()); | ||
case ZADD: | ||
verifyLength(tokens, 4); | ||
return store.zadd(tokens[1], Long.parseLong(tokens[2]), tokens[3]); | ||
case ZCARD: | ||
verifyLength(tokens, 2); | ||
return Integer.toString(store.zcard(tokens[1])); | ||
case ZRANK: | ||
verifyLength(tokens, 3); | ||
return Integer.toString(store.zrank(tokens[1], tokens[2])); | ||
case ZRANGE: | ||
verifyLength(tokens, 4); | ||
return listToString(store.zrange(tokens[1], | ||
Integer.parseInt(tokens[2]), | ||
Integer.parseInt(tokens[3]))); | ||
default: | ||
verbosePrintln("Command " + tokens[0] | ||
+ " is not yet implemented"); | ||
} | ||
} catch (IllegalArgumentException e) { | ||
verbosePrintln("bad command: " + tokens[0]); | ||
return "ERROR bad command"; | ||
} catch (IndexOutOfBoundsException e) { | ||
verbosePrintln("incorrect number of parameters"); | ||
return "ERROR number of parameters"; | ||
} | ||
return null; | ||
} | ||
|
||
private void verifyLength(String[] tokens, int length) { | ||
if (tokens.length != length) { | ||
throw new IllegalArgumentException("incorrect number of parameters"); | ||
} | ||
} | ||
|
||
private String listToString(Iterable<String> list) { | ||
StringBuilder sb = new StringBuilder(); | ||
for (String s : list) { | ||
sb.append(s); | ||
sb.append("\n"); | ||
} | ||
return sb.toString(); | ||
} | ||
|
||
private void verbosePrintln(String msg) { | ||
if (verbose) { | ||
System.out.println(msg); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.kenlai.MKLRedis; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
import org.junit.Test; | ||
|
||
public class CommandProcessorTest { | ||
private static final String OK = "OK"; | ||
private static final String ERROR = "ERROR"; | ||
|
||
private CommandProcessor cp = new CommandProcessor(); | ||
|
||
@Test | ||
public void testProcess() { | ||
assertEquals(OK, cp.process("SET foo bar")); | ||
assertTrue(cp.process("BAD").startsWith(ERROR)); | ||
assertTrue(cp.process("What+is&this?").startsWith(ERROR)); | ||
|
||
assertEquals("1", cp.process("INCR numerical")); | ||
assertEquals("2", cp.process("DBSIZE")); | ||
|
||
assertEquals("bar", cp.process("GET foo")); | ||
assertEquals("1", cp.process("DEL foo")); | ||
assertEquals("0", cp.process("DEL foo")); | ||
assertEquals("1", cp.process("DBSIZE")); | ||
|
||
assertEquals("OK", cp.process("ZADD set 10 ten")); | ||
assertEquals("2", cp.process("DBSIZE")); | ||
assertEquals("1", cp.process("ZCARD set")); | ||
assertEquals("OK", cp.process("ZADD set 10 tenB")); | ||
assertEquals("1", cp.process("ZRANK set tenB")); | ||
assertEquals("tenB\n", cp.process("ZRANGE set -1 -1")); | ||
|
||
assertTrue(cp.process("GET set").startsWith(ERROR)); | ||
assertTrue(cp.process("INCR set").startsWith(ERROR)); | ||
|
||
assertEquals("1", cp.process("DEL set")); | ||
assertEquals("1", cp.process("DBSIZE")); | ||
} | ||
|
||
} |