-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
93a0093
commit b509dfc
Showing
14 changed files
with
742 additions
and
9 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
123 changes: 123 additions & 0 deletions
123
core/src/main/java/dev/keva/core/command/impl/zset/ZAdd.java
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,123 @@ | ||
package dev.keva.core.command.impl.zset; | ||
|
||
import dev.keva.core.command.annotation.CommandImpl; | ||
import dev.keva.core.command.annotation.Execute; | ||
import dev.keva.core.command.annotation.Mutate; | ||
import dev.keva.core.command.annotation.ParamLength; | ||
import dev.keva.ioc.annotation.Autowired; | ||
import dev.keva.ioc.annotation.Component; | ||
import dev.keva.protocol.resp.reply.BulkReply; | ||
import dev.keva.protocol.resp.reply.ErrorReply; | ||
import dev.keva.protocol.resp.reply.IntegerReply; | ||
import dev.keva.protocol.resp.reply.Reply; | ||
import dev.keva.store.KevaDatabase; | ||
import dev.keva.util.DoubleUtil; | ||
import dev.keva.util.hashbytes.BytesKey; | ||
|
||
import java.nio.charset.StandardCharsets; | ||
import java.util.AbstractMap.SimpleEntry; | ||
|
||
import static dev.keva.util.Constants.FLAG_CH; | ||
import static dev.keva.util.Constants.FLAG_GT; | ||
import static dev.keva.util.Constants.FLAG_INCR; | ||
import static dev.keva.util.Constants.FLAG_LT; | ||
import static dev.keva.util.Constants.FLAG_NX; | ||
import static dev.keva.util.Constants.FLAG_XX; | ||
|
||
@Component | ||
@CommandImpl("zadd") | ||
@ParamLength(type = ParamLength.Type.AT_LEAST, value = 3) | ||
@Mutate | ||
public final class ZAdd { | ||
private static final String XX = "xx"; | ||
private static final String NX = "nx"; | ||
private static final String GT = "gt"; | ||
private static final String LT = "lt"; | ||
private static final String INCR = "incr"; | ||
private static final String CH = "ch"; | ||
|
||
private final KevaDatabase database; | ||
|
||
@Autowired | ||
public ZAdd(KevaDatabase database) { | ||
this.database = database; | ||
} | ||
|
||
@Execute | ||
public Reply<?> execute(byte[][] params) { | ||
// Parse the flags, if any | ||
boolean xx = false, nx = false, gt = false, lt = false, incr = false; | ||
int argPos = 1, flags = 0; | ||
String arg; | ||
while (argPos < params.length) { | ||
arg = new String(params[argPos], StandardCharsets.UTF_8); | ||
if (XX.equalsIgnoreCase(arg)) { | ||
xx = true; | ||
flags |= FLAG_XX; | ||
} else if (NX.equalsIgnoreCase(arg)) { | ||
nx = true; | ||
flags |= FLAG_NX; | ||
} else if (GT.equalsIgnoreCase(arg)) { | ||
gt = true; | ||
flags |= FLAG_GT; | ||
} else if (LT.equalsIgnoreCase(arg)) { | ||
lt = true; | ||
flags |= FLAG_LT; | ||
} else if (INCR.equalsIgnoreCase(arg)) { | ||
incr = true; | ||
flags |= FLAG_INCR; | ||
} else if (CH.equalsIgnoreCase(arg)) { | ||
flags |= FLAG_CH; | ||
} else { | ||
break; | ||
} | ||
++argPos; | ||
} | ||
|
||
int numMembers = params.length - argPos; | ||
if (numMembers % 2 != 0) { | ||
return ErrorReply.SYNTAX_ERROR; | ||
} | ||
numMembers /= 2; | ||
|
||
if (nx && xx) { | ||
return ErrorReply.ZADD_NX_XX_ERROR; | ||
} | ||
if ((gt && nx) || (lt && nx) || (gt && lt)) { | ||
return ErrorReply.ZADD_GT_LT_NX_ERROR; | ||
} | ||
if (incr && numMembers > 1) { | ||
return ErrorReply.ZADD_INCR_ERROR; | ||
} | ||
|
||
// Parse the key and value | ||
final SimpleEntry<Double, BytesKey>[] members = new SimpleEntry[numMembers]; | ||
double score; | ||
String rawScore; | ||
for (int memberIndex = 0; memberIndex < numMembers; ++memberIndex) { | ||
try { | ||
rawScore = new String(params[argPos++], StandardCharsets.UTF_8); | ||
if (rawScore.equalsIgnoreCase("inf") || rawScore.equalsIgnoreCase("infinity") | ||
|| rawScore.equalsIgnoreCase("+inf") || rawScore.equalsIgnoreCase("+infinity") | ||
) { | ||
score = Double.POSITIVE_INFINITY; | ||
} else if (rawScore.equalsIgnoreCase("-inf") || rawScore.equalsIgnoreCase("-infinity")) { | ||
score = Double.NEGATIVE_INFINITY; | ||
} else { | ||
score = Double.parseDouble(rawScore); | ||
} | ||
} catch (final NumberFormatException ignored) { | ||
// return on first bad input | ||
return ErrorReply.ZADD_SCORE_FLOAT_ERROR; | ||
} | ||
members[memberIndex] = new SimpleEntry<>(score, new BytesKey(params[argPos++])); | ||
} | ||
|
||
if (incr) { | ||
Double result = database.zincrby(params[0], members[0].getKey(), members[0].getValue(), flags); | ||
return result == null ? BulkReply.NIL_REPLY : new BulkReply(DoubleUtil.toString(result)); | ||
} | ||
int result = database.zadd(params[0], members, flags); | ||
return new IntegerReply(result); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
core/src/main/java/dev/keva/core/command/impl/zset/ZScore.java
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,36 @@ | ||
package dev.keva.core.command.impl.zset; | ||
|
||
import dev.keva.core.command.annotation.CommandImpl; | ||
import dev.keva.core.command.annotation.Execute; | ||
import dev.keva.core.command.annotation.ParamLength; | ||
import dev.keva.ioc.annotation.Autowired; | ||
import dev.keva.ioc.annotation.Component; | ||
import dev.keva.protocol.resp.reply.BulkReply; | ||
import dev.keva.store.KevaDatabase; | ||
|
||
@Component | ||
@CommandImpl("zscore") | ||
@ParamLength(type = ParamLength.Type.EXACT, value = 2) | ||
public final class ZScore { | ||
private final KevaDatabase database; | ||
|
||
@Autowired | ||
public ZScore(KevaDatabase database) { | ||
this.database = database; | ||
} | ||
|
||
@Execute | ||
public BulkReply execute(byte[] key, byte[] member) { | ||
final Double result = database.zscore(key, member); | ||
if(result == null){ | ||
return BulkReply.NIL_REPLY; | ||
} | ||
if (result.equals(Double.POSITIVE_INFINITY)) { | ||
return BulkReply.POSITIVE_INFINITY_REPLY; | ||
} | ||
if (result.equals(Double.NEGATIVE_INFINITY)) { | ||
return BulkReply.NEGATIVE_INFINITY_REPLY; | ||
} | ||
return new BulkReply(result.toString()); | ||
} | ||
} |
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
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
Oops, something went wrong.