You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by do...@apache.org on 2021/05/14 14:48:13 UTC
[geode] branch develop updated: GEODE-9221: Remove uses of
ByteArrayWrapper from RedisString (#6464)
This is an automated email from the ASF dual-hosted git repository.
donalevans pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new cbda688 GEODE-9221: Remove uses of ByteArrayWrapper from RedisString (#6464)
cbda688 is described below
commit cbda688f15c2e6a270a2f6041a70d648d58aa748
Author: Donal Evans <do...@vmware.com>
AuthorDate: Fri May 14 07:47:12 2021 -0700
GEODE-9221: Remove uses of ByteArrayWrapper from RedisString (#6464)
- Replace uses of ByteArrayWrapper in RedisString and NullRedisString
with byte[]
- Remove unused methods from ByteArrayWrapper
- Populate RedisString.bitcountTable at initialization time via static method
- Added integration tests for RedisString.bitpos
- Refactor to remove warnings
Authored-by: Donal Evans <do...@vmware.com>
---
.../hash/MemoryOverheadIntegrationTest.java | 2 +-
.../string/AbstractBitPosIntegrationTest.java | 57 +++
.../codeAnalysis/sanctionedDataSerializables.txt | 4 +-
.../redis/internal/data/ByteArrayWrapper.java | 14 -
.../geode/redis/internal/data/CommandHelper.java | 2 +-
.../geode/redis/internal/data/NullRedisString.java | 77 ++--
.../geode/redis/internal/data/RedisString.java | 413 ++++-----------------
.../data/RedisStringCommandsFunctionExecutor.java | 40 +-
.../redis/internal/executor/CommandFunction.java | 6 +-
.../internal/executor/string/AppendExecutor.java | 7 +-
.../internal/executor/string/GetExecutor.java | 6 +-
.../internal/executor/string/GetRangeExecutor.java | 5 +-
.../internal/executor/string/GetSetExecutor.java | 4 +-
.../internal/executor/string/MGetExecutor.java | 3 +-
.../internal/executor/string/MSetExecutor.java | 4 +-
.../internal/executor/string/MSetNXExecutor.java | 4 +-
.../executor/string/RedisStringCommands.java | 13 +-
.../string/RedisStringCommandsFunctionInvoker.java | 13 +-
.../internal/executor/string/SetEXExecutor.java | 3 +-
.../internal/executor/string/SetExecutor.java | 17 +-
.../internal/executor/string/SetNXExecutor.java | 4 +-
.../redis/internal/executor/string/SetOptions.java | 5 +-
.../apache/geode/redis/internal/netty/Coder.java | 20 +-
.../geode/redis/internal/data/RedisStringTest.java | 360 ++++++++----------
24 files changed, 391 insertions(+), 692 deletions(-)
diff --git a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/hash/MemoryOverheadIntegrationTest.java b/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/hash/MemoryOverheadIntegrationTest.java
index f22c242..eae64bb 100755
--- a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/hash/MemoryOverheadIntegrationTest.java
+++ b/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/hash/MemoryOverheadIntegrationTest.java
@@ -53,7 +53,7 @@ public class MemoryOverheadIntegrationTest extends AbstractMemoryOverheadIntegra
@Override
EnumMap<Measurement, Integer> expectedPerEntryOverhead() {
EnumMap<Measurement, Integer> result = new EnumMap<>(Measurement.class);
- result.put(Measurement.STRING, 201);
+ result.put(Measurement.STRING, 185);
result.put(Measurement.SET, 386);
result.put(Measurement.SET_ENTRY, 72);
result.put(Measurement.HASH, 490);
diff --git a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/string/AbstractBitPosIntegrationTest.java b/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/string/AbstractBitPosIntegrationTest.java
index e1a498b..c0c468f 100755
--- a/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/string/AbstractBitPosIntegrationTest.java
+++ b/geode-apis-compatible-with-redis/src/integrationTest/java/org/apache/geode/redis/internal/executor/string/AbstractBitPosIntegrationTest.java
@@ -76,6 +76,14 @@ public abstract class AbstractBitPosIntegrationTest implements RedisIntegrationT
}
@Test
+ public void bitpos_givenStartGreaterThanEnd() {
+ byte[] key = {1, 2, 3};
+ byte[] bytes = {1, 1, 1, 1, 1};
+ jedis.set(key, bytes);
+ assertThat(jedis.bitpos(key, true, new BitPosParams(3, 2))).isEqualTo(-1);
+ }
+
+ @Test
public void bitpos_givenBitInFirstByte() {
byte[] key = {1, 2, 3};
byte[] bytes = {1, 1, 1, 1, 1};
@@ -116,10 +124,59 @@ public abstract class AbstractBitPosIntegrationTest implements RedisIntegrationT
}
@Test
+ public void bitposWithStartAndEnd_givenStartAndEndEqual() {
+ byte[] key = {1, 2, 3};
+ byte[] bytes = {1, 1, 1, 1};
+ jedis.set(key, bytes);
+ assertThat(jedis.bitpos(key, true, new BitPosParams(2, 2))).isEqualTo(7 + 2 * 8);
+ }
+
+ @Test
+ public void bitposWithStartAndEnd_givenStartAndEndNegative() {
+ byte[] key = {1, 2, 3};
+ byte[] bytes = {1, 1, 1, 1};
+ jedis.set(key, bytes);
+ assertThat(jedis.bitpos(key, true, new BitPosParams(-2, -1))).isEqualTo(7 + 2 * 8);
+ }
+
+ @Test
+ public void bitposWithStartAndEnd_givenEndGreaterThanOrEqualToByteArrayLength() {
+ byte[] key = {1, 2, 3};
+ byte[] bytes = {1, 1, 1, 1};
+ jedis.set(key, bytes);
+ assertThat(jedis.bitpos(key, true, new BitPosParams(0, bytes.length))).isEqualTo(7);
+ assertThat(jedis.bitpos(key, true, new BitPosParams(0, bytes.length + 1))).isEqualTo(7);
+ }
+
+ @Test
public void bitposWithStartAndEnd_givenNoBits() {
byte[] key = {1, 2, 3};
byte[] bytes = {1, 0, 0, 1};
jedis.set(key, bytes);
assertThat(jedis.bitpos(key, true, new BitPosParams(1, 2))).isEqualTo(-1);
}
+
+ @Test
+ public void bitposWithStart_givenStartMoreNegativeThanByteArrayLength() {
+ byte[] key = {1, 2, 3};
+ byte[] bytes = {1, 1, 1, 1};
+ jedis.set(key, bytes);
+ assertThat(jedis.bitpos(key, true, new BitPosParams(-(bytes.length + 1)))).isEqualTo(7);
+ }
+
+ @Test
+ public void bitposFalseWithStartAndEnd_givenEndGreaterThanByteArrayLengthAndNoBitFound() {
+ byte[] key = {1, 2, 3};
+ byte[] bytes = {-1, -1, -1, -1};
+ jedis.set(key, bytes);
+ assertThat(jedis.bitpos(key, false, new BitPosParams(0, bytes.length))).isEqualTo(-1);
+ }
+
+ @Test
+ public void bitposFalseWithStart_givenNoBitFound() {
+ byte[] key = {1, 2, 3};
+ byte[] bytes = {-1, -1, -1, -1};
+ jedis.set(key, bytes);
+ assertThat(jedis.bitpos(key, false, new BitPosParams(0))).isEqualTo(bytes.length * 8);
+ }
}
diff --git a/geode-apis-compatible-with-redis/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt b/geode-apis-compatible-with-redis/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
index c97c184..38b06fc 100644
--- a/geode-apis-compatible-with-redis/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
+++ b/geode-apis-compatible-with-redis/src/integrationTest/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
@@ -23,8 +23,8 @@ toData,26
fromData,26
org/apache/geode/redis/internal/data/RedisString,2
-toData,26
-fromData,30
+toData,23
+fromData,23
org/apache/geode/redis/internal/executor/string/SetOptions,2
fromData,34
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/ByteArrayWrapper.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/ByteArrayWrapper.java
index 79d4f4f..046914a 100755
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/ByteArrayWrapper.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/ByteArrayWrapper.java
@@ -147,20 +147,6 @@ public class ByteArrayWrapper
return 0;
}
-
- private static byte[] concatArrays(byte[] o, byte[] n) {
- int oLen = o.length;
- int nLen = n.length;
- byte[] combined = new byte[oLen + nLen];
- System.arraycopy(o, 0, combined, 0, oLen);
- System.arraycopy(n, 0, combined, oLen, nLen);
- return combined;
- }
-
- public void append(byte[] appendBytes) {
- setBytes(concatArrays(value, appendBytes));
- }
-
@Override
public int getDSFID() {
return DataSerializableFixedID.REDIS_BYTE_ARRAY_WRAPPER;
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/CommandHelper.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/CommandHelper.java
index e78c963..2e7c524 100644
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/CommandHelper.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/CommandHelper.java
@@ -166,7 +166,7 @@ public class CommandHelper {
return checkStringType(redisData, true);
}
- RedisString setRedisString(RedisKey key, ByteArrayWrapper value) {
+ RedisString setRedisString(RedisKey key, byte[] value) {
RedisString result;
RedisData redisData = getRedisData(key);
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/NullRedisString.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/NullRedisString.java
index 684778a..31a9c85 100644
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/NullRedisString.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/NullRedisString.java
@@ -38,7 +38,7 @@ import org.apache.geode.redis.internal.netty.Coder;
*/
public class NullRedisString extends RedisString {
public NullRedisString() {
- super(new ByteArrayWrapper(new byte[0]));
+ super(new byte[0]);
}
@Override
@@ -52,23 +52,17 @@ public class NullRedisString extends RedisString {
}
@Override
- protected void valueSet(ByteArrayWrapper newValue) {
+ protected void valueSet(byte[] bytes) {
throw new UnsupportedOperationException();
}
@Override
- protected void valueSetBytes(byte[] bytes) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ByteArrayWrapper get() {
+ public byte[] get() {
return null;
}
@Override
- public int bitpos(Region<RedisKey, RedisData> region, RedisKey key, int bit,
- int start, Integer end) {
+ public int bitpos(int bit, int start, Integer end) {
if (bit == 0) {
return 0;
} else {
@@ -83,10 +77,10 @@ public class NullRedisString extends RedisString {
if (bitValue == 1) {
byte[] bytes = new byte[byteIndex + 1];
bytes[byteIndex] = (byte) (0x80 >> bitIndex);
- newValue = new RedisString(new ByteArrayWrapper(bytes));
+ newValue = new RedisString(bytes);
} else {
// all bits are 0 so use an empty byte array
- newValue = new RedisString(new ByteArrayWrapper(new byte[0]));
+ newValue = new RedisString(new byte[0]);
}
region.put(key, newValue);
return 0;
@@ -96,7 +90,7 @@ public class NullRedisString extends RedisString {
public long incr(Region<RedisKey, RedisData> region, RedisKey key)
throws NumberFormatException, ArithmeticException {
byte[] newValue = {Coder.NUMBER_1_BYTE};
- region.put(key, new RedisString(new ByteArrayWrapper(newValue)));
+ region.put(key, new RedisString(newValue));
return 1;
}
@@ -104,7 +98,7 @@ public class NullRedisString extends RedisString {
public long incrby(Region<RedisKey, RedisData> region, RedisKey key,
long increment) throws NumberFormatException, ArithmeticException {
byte[] newValue = Coder.longToBytes(increment);
- region.put(key, new RedisString(new ByteArrayWrapper(newValue)));
+ region.put(key, new RedisString(newValue));
return increment;
}
@@ -112,34 +106,32 @@ public class NullRedisString extends RedisString {
public BigDecimal incrbyfloat(Region<RedisKey, RedisData> region, RedisKey key,
BigDecimal increment) throws NumberFormatException, ArithmeticException {
byte[] newValue = Coder.bigDecimalToBytes(increment);
- region.put(key, new RedisString(new ByteArrayWrapper(newValue)));
+ region.put(key, new RedisString(newValue));
return increment;
}
@Override
public long decr(Region<RedisKey, RedisData> region, RedisKey key)
throws NumberFormatException, ArithmeticException {
- region.put(key, new RedisString(new ByteArrayWrapper(Coder.stringToBytes("-1"))));
+ region.put(key, new RedisString(Coder.stringToBytes("-1")));
return -1;
}
@Override
public long decrby(Region<RedisKey, RedisData> region, RedisKey key, long decrement) {
byte[] newValue = Coder.longToBytes(-decrement);
- region.put(key, new RedisString(new ByteArrayWrapper(newValue)));
+ region.put(key, new RedisString(newValue));
return -decrement;
}
@Override
- public int append(ByteArrayWrapper appendValue, Region<RedisKey, RedisData> region,
- RedisKey key) {
+ public int append(Region<RedisKey, RedisData> region, RedisKey key, byte[] appendValue) {
region.put(key, new RedisString(appendValue));
- return appendValue.length();
+ return appendValue.length;
}
@Override
- public ByteArrayWrapper getset(Region<RedisKey, RedisData> region, RedisKey key,
- ByteArrayWrapper value) {
+ public byte[] getset(Region<RedisKey, RedisData> region, RedisKey key, byte[] value) {
region.put(key, new RedisString(value));
return null;
}
@@ -153,7 +145,7 @@ public class NullRedisString extends RedisString {
newBytes = new byte[offset + valueToAdd.length];
System.arraycopy(valueToAdd, 0, newBytes, offset, valueToAdd.length);
}
- region.put(key, new RedisString(new ByteArrayWrapper(newBytes)));
+ region.put(key, new RedisString(newBytes));
}
return newBytes.length;
}
@@ -162,8 +154,7 @@ public class NullRedisString extends RedisString {
* SET is currently mostly implemented here. It does not have an implementation on
* RedisString which is a bit odd.
*/
- public boolean set(CommandHelper helper, RedisKey key, ByteArrayWrapper value,
- SetOptions options) {
+ public boolean set(CommandHelper helper, RedisKey key, byte[] value, SetOptions options) {
if (options != null) {
if (options.isNX()) {
return setnx(helper, key, value, options);
@@ -179,8 +170,7 @@ public class NullRedisString extends RedisString {
return true;
}
- private boolean setnx(CommandHelper helper, RedisKey key, ByteArrayWrapper value,
- SetOptions options) {
+ private boolean setnx(CommandHelper helper, RedisKey key, byte[] value, SetOptions options) {
if (helper.getRedisData(key).exists()) {
return false;
}
@@ -196,7 +186,7 @@ public class NullRedisString extends RedisString {
* that care if a RedisString for "key" exists.
*/
public int bitop(CommandHelper helper, String operation, RedisKey key, List<RedisKey> sources) {
- List<ByteArrayWrapper> sourceValues = new ArrayList<>();
+ List<byte[]> sourceValues = new ArrayList<>();
int selfIndex = -1;
// Read all the source values, except for self, before locking the stripe.
RedisStringCommands commander =
@@ -221,7 +211,7 @@ public class NullRedisString extends RedisString {
}
private int doBitOp(CommandHelper helper, String operation, RedisKey key, int selfIndex,
- List<ByteArrayWrapper> sourceValues) {
+ List<byte[]> sourceValues) {
if (selfIndex != -1) {
RedisString redisString = helper.getRedisString(key, true);
if (!redisString.isNull()) {
@@ -229,12 +219,12 @@ public class NullRedisString extends RedisString {
}
}
int maxLength = 0;
- for (ByteArrayWrapper sourceValue : sourceValues) {
- if (sourceValue != null && maxLength < sourceValue.length()) {
- maxLength = sourceValue.length();
+ for (byte[] sourceValue : sourceValues) {
+ if (sourceValue != null && maxLength < sourceValue.length) {
+ maxLength = sourceValue.length;
}
}
- ByteArrayWrapper newValue;
+ byte[] newValue;
switch (operation) {
case "AND":
newValue = doBitOp(BitOp.AND, sourceValues, maxLength);
@@ -249,23 +239,23 @@ public class NullRedisString extends RedisString {
newValue = not(sourceValues.get(0), maxLength);
break;
}
- if (newValue.length() == 0) {
+ if (newValue.length == 0) {
helper.getRegion().remove(key);
} else {
helper.setRedisString(key, newValue);
}
- return newValue.length();
+ return newValue.length;
}
- private ByteArrayWrapper doBitOp(BitOp bitOp, List<ByteArrayWrapper> sourceValues, int max) {
+ private byte[] doBitOp(BitOp bitOp, List<byte[]> sourceValues, int max) {
byte[] dest = new byte[max];
for (int i = 0; i < max; i++) {
byte b = 0;
boolean firstByte = true;
- for (ByteArrayWrapper sourceValue : sourceValues) {
+ for (byte[] sourceValue : sourceValues) {
byte sourceByte = 0;
- if (sourceValue != null && i < sourceValue.length()) {
- sourceByte = sourceValue.toBytes()[i];
+ if (sourceValue != null && i < sourceValue.length) {
+ sourceByte = sourceValue[i];
}
if (firstByte) {
b = sourceByte;
@@ -286,22 +276,21 @@ public class NullRedisString extends RedisString {
}
dest[i] = b;
}
- return new ByteArrayWrapper(dest);
+ return dest;
}
- private ByteArrayWrapper not(ByteArrayWrapper sourceValue, int max) {
+ private byte[] not(byte[] sourceValue, int max) {
byte[] dest = new byte[max];
if (sourceValue == null) {
for (int i = 0; i < max; i++) {
dest[i] = ~0;
}
} else {
- byte[] cA = sourceValue.toBytes();
for (int i = 0; i < max; i++) {
- dest[i] = (byte) (~cA[i] & 0xFF);
+ dest[i] = (byte) (~sourceValue[i] & 0xFF);
}
}
- return new ByteArrayWrapper(dest);
+ return dest;
}
}
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/RedisString.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/RedisString.java
index df04cdb..c3475ae 100644
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/RedisString.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/RedisString.java
@@ -37,34 +37,36 @@ import org.apache.geode.redis.internal.netty.Coder;
public class RedisString extends AbstractRedisData {
private int appendSequence;
- private ByteArrayWrapper value;
+ private byte[] value;
// this value is empirically derived using ReflectionObjectSizer, which provides an exact size
// of the object. It can't be used directly because of its performance impact. This value causes
// the size we keep track of to converge to the actual size as it increases.
- protected static final int BASE_REDIS_STRING_OVERHEAD = 64;
+ protected static final int BASE_REDIS_STRING_OVERHEAD = 48;
- public RedisString(ByteArrayWrapper value) {
+ // An array containing the number of set bits for each value from 0x00 to 0xff
+ private static final byte[] bitCountTable = getBitCountTable();
+
+ public RedisString(byte[] value) {
this.value = value;
}
// for serialization
public RedisString() {}
- public ByteArrayWrapper get() {
- return new ByteArrayWrapper(value.toBytes());
+ public byte[] get() {
+ return value;
}
- public void set(ByteArrayWrapper value) {
- valueSet(value);
+ public void set(byte[] value) {
+ this.value = value;
}
- public int append(ByteArrayWrapper appendValue, Region<RedisKey, RedisData> region,
- RedisKey key) {
- valueAppend(appendValue.toBytes());
+ public int append(Region<RedisKey, RedisData> region, RedisKey key, byte[] appendValue) {
+ valueAppend(appendValue);
appendSequence++;
- storeChanges(region, key, new AppendDeltaInfo(appendValue.toBytes(), appendSequence));
- return value.length();
+ storeChanges(region, key, new AppendDeltaInfo(appendValue, appendSequence));
+ return value.length;
}
public long incr(Region<RedisKey, RedisData> region, RedisKey key)
@@ -74,7 +76,7 @@ public class RedisString extends AbstractRedisData {
throw new ArithmeticException(RedisConstants.ERROR_OVERFLOW);
}
longValue++;
- valueSetBytes(Coder.longToBytes(longValue));
+ value = Coder.longToBytes(longValue);
// numeric strings are short so no need to use delta
region.put(key, this);
return longValue;
@@ -87,7 +89,7 @@ public class RedisString extends AbstractRedisData {
throw new ArithmeticException(RedisConstants.ERROR_OVERFLOW);
}
longValue += increment;
- valueSetBytes(Coder.longToBytes(longValue));
+ value = Coder.longToBytes(longValue);
// numeric strings are short so no need to use delta
region.put(key, this);
return longValue;
@@ -98,7 +100,7 @@ public class RedisString extends AbstractRedisData {
throws NumberFormatException, ArithmeticException {
BigDecimal bigDecimalValue = parseValueAsBigDecimal();
bigDecimalValue = bigDecimalValue.add(increment);
- valueSetBytes(Coder.bigDecimalToBytes(bigDecimalValue));
+ value = Coder.bigDecimalToBytes(bigDecimalValue);
// numeric strings are short so no need to use delta
region.put(key, this);
@@ -111,7 +113,7 @@ public class RedisString extends AbstractRedisData {
throw new ArithmeticException(RedisConstants.ERROR_OVERFLOW);
}
longValue -= decrement;
- valueSetBytes(Coder.longToBytes(longValue));
+ value = Coder.longToBytes(longValue);
// numeric strings are short so no need to use delta
region.put(key, this);
return longValue;
@@ -124,7 +126,7 @@ public class RedisString extends AbstractRedisData {
throw new ArithmeticException(RedisConstants.ERROR_OVERFLOW);
}
longValue--;
- valueSetBytes(Coder.longToBytes(longValue));
+ value = Coder.longToBytes(longValue);
// numeric strings are short so no need to use delta
region.put(key, this);
return longValue;
@@ -132,14 +134,14 @@ public class RedisString extends AbstractRedisData {
private long parseValueAsLong() {
try {
- return Long.parseLong(value.toString());
+ return Coder.bytesToLong(value);
} catch (NumberFormatException ex) {
throw new NumberFormatException(RedisConstants.ERROR_NOT_INTEGER);
}
}
private BigDecimal parseValueAsBigDecimal() {
- String valueString = value.toString();
+ String valueString = Coder.bytesToString(value);
if (valueString.contains(" ")) {
throw new NumberFormatException(RedisConstants.ERROR_NOT_A_VALID_FLOAT);
}
@@ -150,44 +152,39 @@ public class RedisString extends AbstractRedisData {
}
}
- public ByteArrayWrapper getrange(long start, long end) {
- int length = value.length();
+ public byte[] getrange(long start, long end) {
+ int length = value.length;
int boundedStart = getBoundedStartIndex(start, length);
int boundedEnd = getBoundedEndIndex(end, length);
- /*
- * Can't 'start' at end of value
- */
+ // Can't 'start' at end of value
if (boundedStart > boundedEnd || boundedStart == length) {
- return new ByteArrayWrapper(new byte[0]);
+ return new byte[0];
}
- /*
- * 1 is added to end because the end in copyOfRange is exclusive but in Redis it is inclusive
- */
+ // 1 is added to end because the end in copyOfRange is exclusive but in Redis it is inclusive
if (boundedEnd != length) {
boundedEnd++;
}
- byte[] returnRange = Arrays.copyOfRange(value.toBytes(), boundedStart, boundedEnd);
- return new ByteArrayWrapper(returnRange);
+ return Arrays.copyOfRange(value, boundedStart, boundedEnd);
}
public int setrange(Region<RedisKey, RedisData> region, RedisKey key, int offset,
byte[] valueToAdd) {
if (valueToAdd.length == 0) {
- return value.length();
+ return value.length;
}
int totalLength = offset + valueToAdd.length;
- byte[] bytes = value.toBytes();
+ byte[] bytes = value;
if (totalLength < bytes.length) {
System.arraycopy(valueToAdd, 0, bytes, offset, valueToAdd.length);
} else {
byte[] newBytes = Arrays.copyOf(bytes, totalLength);
System.arraycopy(valueToAdd, 0, newBytes, offset, valueToAdd.length);
- valueSetBytes(newBytes);
+ value = newBytes;
}
// TODO add delta support
region.put(key, this);
- return value.length();
+ return value.length;
}
private int getBoundedStartIndex(long index, int size) {
@@ -206,9 +203,8 @@ public class RedisString extends AbstractRedisData {
}
}
- public int bitpos(Region<RedisKey, RedisData> region, RedisKey key, int bit,
- int start, Integer end) {
- int length = value.length();
+ public int bitpos(int bit, int start, Integer end) {
+ int length = value.length;
if (length == 0) {
return -1;
}
@@ -216,6 +212,8 @@ public class RedisString extends AbstractRedisData {
if (!endSet) {
end = length - 1;
}
+
+ // BITPOS allows indexing from the end of the string using negative values for start and end
if (start < 0) {
start += length;
}
@@ -230,10 +228,10 @@ public class RedisString extends AbstractRedisData {
end = 0;
}
- if (start > length) {
+ if (start >= length) {
start = length - 1;
}
- if (end > length) {
+ if (end >= length) {
end = length - 1;
}
@@ -241,10 +239,9 @@ public class RedisString extends AbstractRedisData {
return -1;
}
- byte[] bytes = value.toBytes();
for (int i = start; i <= end; i++) {
int cBit;
- byte cByte = bytes[i];
+ byte cByte = value[i];
for (int j = 0; j < 8; j++) {
cBit = (cByte & (0x80 >> j)) >> (7 - j);
if (cBit == bit) {
@@ -260,13 +257,12 @@ public class RedisString extends AbstractRedisData {
return -1;
}
-
public long bitcount(int start, int end) {
if (start < 0) {
- start += value.length();
+ start += value.length;
}
if (end < 0) {
- end += value.length();
+ end += value.length;
}
if (start < 0) {
@@ -276,312 +272,52 @@ public class RedisString extends AbstractRedisData {
end = 0;
}
- if (end > value.length() - 1) {
- end = value.length() - 1;
+ if (end > value.length - 1) {
+ end = value.length - 1;
}
- if (end < start || start >= value.length()) {
+ if (end < start) {
return 0;
}
long setBits = 0;
for (int j = start; j <= end; j++) {
- setBits += bitcountTable[0xFF & value.toBytes()[j]];
+ setBits += bitCountTable[0xFF & value[j]];
}
return setBits;
}
public long bitcount() {
- return bitcount(0, value.length() - 1);
- }
-
- private static final byte[] bitcountTable = {
- 0, // 0x0
- 1, // 0x1
- 1, // 0x2
- 2, // 0x3
- 1, // 0x4
- 2, // 0x5
- 2, // 0x6
- 3, // 0x7
- 1, // 0x8
- 2, // 0x9
- 2, // 0xa
- 3, // 0xb
- 2, // 0xc
- 3, // 0xd
- 3, // 0xe
- 4, // 0xf
- 1, // 0x10
- 2, // 0x11
- 2, // 0x12
- 3, // 0x13
- 2, // 0x14
- 3, // 0x15
- 3, // 0x16
- 4, // 0x17
- 2, // 0x18
- 3, // 0x19
- 3, // 0x1a
- 4, // 0x1b
- 3, // 0x1c
- 4, // 0x1d
- 4, // 0x1e
- 5, // 0x1f
- 1, // 0x20
- 2, // 0x21
- 2, // 0x22
- 3, // 0x23
- 2, // 0x24
- 3, // 0x25
- 3, // 0x26
- 4, // 0x27
- 2, // 0x28
- 3, // 0x29
- 3, // 0x2a
- 4, // 0x2b
- 3, // 0x2c
- 4, // 0x2d
- 4, // 0x2e
- 5, // 0x2f
- 2, // 0x30
- 3, // 0x31
- 3, // 0x32
- 4, // 0x33
- 3, // 0x34
- 4, // 0x35
- 4, // 0x36
- 5, // 0x37
- 3, // 0x38
- 4, // 0x39
- 4, // 0x3a
- 5, // 0x3b
- 4, // 0x3c
- 5, // 0x3d
- 5, // 0x3e
- 6, // 0x3f
- 1, // 0x40
- 2, // 0x41
- 2, // 0x42
- 3, // 0x43
- 2, // 0x44
- 3, // 0x45
- 3, // 0x46
- 4, // 0x47
- 2, // 0x48
- 3, // 0x49
- 3, // 0x4a
- 4, // 0x4b
- 3, // 0x4c
- 4, // 0x4d
- 4, // 0x4e
- 5, // 0x4f
- 2, // 0x50
- 3, // 0x51
- 3, // 0x52
- 4, // 0x53
- 3, // 0x54
- 4, // 0x55
- 4, // 0x56
- 5, // 0x57
- 3, // 0x58
- 4, // 0x59
- 4, // 0x5a
- 5, // 0x5b
- 4, // 0x5c
- 5, // 0x5d
- 5, // 0x5e
- 6, // 0x5f
- 2, // 0x60
- 3, // 0x61
- 3, // 0x62
- 4, // 0x63
- 3, // 0x64
- 4, // 0x65
- 4, // 0x66
- 5, // 0x67
- 3, // 0x68
- 4, // 0x69
- 4, // 0x6a
- 5, // 0x6b
- 4, // 0x6c
- 5, // 0x6d
- 5, // 0x6e
- 6, // 0x6f
- 3, // 0x70
- 4, // 0x71
- 4, // 0x72
- 5, // 0x73
- 4, // 0x74
- 5, // 0x75
- 5, // 0x76
- 6, // 0x77
- 4, // 0x78
- 5, // 0x79
- 5, // 0x7a
- 6, // 0x7b
- 5, // 0x7c
- 6, // 0x7d
- 6, // 0x7e
- 7, // 0x7f
- 1, // 0x80
- 2, // 0x81
- 2, // 0x82
- 3, // 0x83
- 2, // 0x84
- 3, // 0x85
- 3, // 0x86
- 4, // 0x87
- 2, // 0x88
- 3, // 0x89
- 3, // 0x8a
- 4, // 0x8b
- 3, // 0x8c
- 4, // 0x8d
- 4, // 0x8e
- 5, // 0x8f
- 2, // 0x90
- 3, // 0x91
- 3, // 0x92
- 4, // 0x93
- 3, // 0x94
- 4, // 0x95
- 4, // 0x96
- 5, // 0x97
- 3, // 0x98
- 4, // 0x99
- 4, // 0x9a
- 5, // 0x9b
- 4, // 0x9c
- 5, // 0x9d
- 5, // 0x9e
- 6, // 0x9f
- 2, // 0xa0
- 3, // 0xa1
- 3, // 0xa2
- 4, // 0xa3
- 3, // 0xa4
- 4, // 0xa5
- 4, // 0xa6
- 5, // 0xa7
- 3, // 0xa8
- 4, // 0xa9
- 4, // 0xaa
- 5, // 0xab
- 4, // 0xac
- 5, // 0xad
- 5, // 0xae
- 6, // 0xaf
- 3, // 0xb0
- 4, // 0xb1
- 4, // 0xb2
- 5, // 0xb3
- 4, // 0xb4
- 5, // 0xb5
- 5, // 0xb6
- 6, // 0xb7
- 4, // 0xb8
- 5, // 0xb9
- 5, // 0xba
- 6, // 0xbb
- 5, // 0xbc
- 6, // 0xbd
- 6, // 0xbe
- 7, // 0xbf
- 2, // 0xc0
- 3, // 0xc1
- 3, // 0xc2
- 4, // 0xc3
- 3, // 0xc4
- 4, // 0xc5
- 4, // 0xc6
- 5, // 0xc7
- 3, // 0xc8
- 4, // 0xc9
- 4, // 0xca
- 5, // 0xcb
- 4, // 0xcc
- 5, // 0xcd
- 5, // 0xce
- 6, // 0xcf
- 3, // 0xd0
- 4, // 0xd1
- 4, // 0xd2
- 5, // 0xd3
- 4, // 0xd4
- 5, // 0xd5
- 5, // 0xd6
- 6, // 0xd7
- 4, // 0xd8
- 5, // 0xd9
- 5, // 0xda
- 6, // 0xdb
- 5, // 0xdc
- 6, // 0xdd
- 6, // 0xde
- 7, // 0xdf
- 3, // 0xe0
- 4, // 0xe1
- 4, // 0xe2
- 5, // 0xe3
- 4, // 0xe4
- 5, // 0xe5
- 5, // 0xe6
- 6, // 0xe7
- 4, // 0xe8
- 5, // 0xe9
- 5, // 0xea
- 6, // 0xeb
- 5, // 0xec
- 6, // 0xed
- 6, // 0xee
- 7, // 0xef
- 4, // 0xf0
- 5, // 0xf1
- 5, // 0xf2
- 6, // 0xf3
- 5, // 0xf4
- 6, // 0xf5
- 6, // 0xf6
- 7, // 0xf7
- 5, // 0xf8
- 6, // 0xf9
- 6, // 0xfa
- 7, // 0xfb
- 6, // 0xfc
- 7, // 0xfd
- 7, // 0xfe
- 8 // 0xff
- };
-
+ return bitcount(0, value.length - 1);
+ }
public int strlen() {
- return value.length();
+ return value.length;
}
public int getbit(int offset) {
if (offset < 0) {
- offset += value.length() * 8;
+ offset += value.length * 8;
}
- if (offset < 0 || offset > value.length() * 8) {
+ if (offset < 0 || offset > value.length * 8) {
return 0;
}
int byteIndex = offset / 8;
offset %= 8;
- if (byteIndex >= value.length()) {
+ if (byteIndex >= value.length) {
return 0;
}
- return (value.toBytes()[byteIndex] & (0x80 >> offset)) >> (7 - offset);
+ return (value[byteIndex] & (0x80 >> offset)) >> (7 - offset);
}
public int setbit(Region<RedisKey, RedisData> region, RedisKey key,
int bitValue, int byteIndex, byte bitIndex) {
int returnBit;
- byte[] bytes = value.toBytes();
+ byte[] bytes = value;
if (byteIndex < bytes.length) {
returnBit = (bytes[byteIndex] & (0x80 >> bitIndex)) >> (7 - bitIndex);
} else {
@@ -596,7 +332,7 @@ public class RedisString extends AbstractRedisData {
System.arraycopy(bytes, 0, newBytes, 0, bytes.length);
newBytes[byteIndex] = bitValue == 1 ? (byte) (newBytes[byteIndex] | (0x80 >> bitIndex))
: (byte) (newBytes[byteIndex] & ~(0x80 >> bitIndex));
- valueSetBytes(newBytes);
+ value = newBytes;
}
// TODO: add delta support
region.put(key, this);
@@ -613,7 +349,7 @@ public class RedisString extends AbstractRedisData {
public synchronized void toData(DataOutput out, SerializationContext context) throws IOException {
super.toData(out, context);
DataSerializer.writePrimitiveInt(appendSequence, out);
- DataSerializer.writeByteArray(value.toBytes(), out);
+ DataSerializer.writeByteArray(value, out);
}
@Override
@@ -621,7 +357,7 @@ public class RedisString extends AbstractRedisData {
throws IOException, ClassNotFoundException {
super.fromData(in, context);
appendSequence = DataSerializer.readPrimitiveInt(in);
- value = new ByteArrayWrapper(DataSerializer.readByteArray(in));
+ value = DataSerializer.readByteArray(in);
}
@@ -636,7 +372,7 @@ public class RedisString extends AbstractRedisData {
byte[] appendBytes = appendDeltaInfo.getBytes();
if (value == null) {
- value = new ByteArrayWrapper(appendBytes);
+ value = appendBytes;
appendSequence = appendDeltaInfo.getSequence();
} else {
if (appendDeltaInfo.getSequence() == appendSequence + 1) {
@@ -656,11 +392,10 @@ public class RedisString extends AbstractRedisData {
return RedisDataType.REDIS_STRING;
}
- public ByteArrayWrapper getset(Region<RedisKey, RedisData> region, RedisKey key,
- ByteArrayWrapper newValue) {
+ public byte[] getset(Region<RedisKey, RedisData> region, RedisKey key, byte[] newValue) {
// No need to copy "value" since we are locked and will be calling set which replaces
// "value" with a new instance.
- ByteArrayWrapper result = value;
+ byte[] result = value;
set(newValue);
persistNoDelta();
region.put(key, this);
@@ -684,7 +419,7 @@ public class RedisString extends AbstractRedisData {
return false;
}
RedisString that = (RedisString) o;
- return Objects.equals(value, that.value);
+ return Arrays.equals(value, that.value);
}
@Override
@@ -692,7 +427,7 @@ public class RedisString extends AbstractRedisData {
return Objects.hash(super.hashCode(), value);
}
- ByteArrayWrapper getValue() {
+ byte[] getValue() {
return value;
}
@@ -700,7 +435,7 @@ public class RedisString extends AbstractRedisData {
public String toString() {
return "RedisString{" +
super.toString() + ", " +
- "value=" + value +
+ "value=" + new String(value) +
'}';
}
@@ -718,15 +453,17 @@ public class RedisString extends AbstractRedisData {
////// methods that modify the "value" field ////////////
protected void valueAppend(byte[] bytes) {
- value.append(bytes);
- }
-
- protected void valueSet(ByteArrayWrapper newValue) {
- value = newValue;
+ int initialLength = value.length;
+ int additionalLength = bytes.length;
+ byte[] combined = new byte[initialLength + additionalLength];
+ System.arraycopy(value, 0, combined, 0, initialLength);
+ System.arraycopy(bytes, 0, combined, initialLength, additionalLength);
+ value = combined;
}
- protected void valueSetBytes(byte[] bytes) {
- value.setBytes(bytes);
+ @SuppressWarnings("unused")
+ protected void valueSet(byte[] bytes) {
+ value = bytes;
}
@Override
@@ -736,6 +473,14 @@ public class RedisString extends AbstractRedisData {
@Override
public int getSizeInBytes() {
- return BASE_REDIS_STRING_OVERHEAD + value.length();
+ return BASE_REDIS_STRING_OVERHEAD + value.length;
+ }
+
+ private static byte[] getBitCountTable() {
+ byte[] table = new byte[256];
+ for (int i = 0; i < table.length; ++i) {
+ table[i] = (byte) Integer.bitCount(i);
+ }
+ return table;
}
}
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/RedisStringCommandsFunctionExecutor.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/RedisStringCommandsFunctionExecutor.java
index f9e6595..ce62e74 100644
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/RedisStringCommandsFunctionExecutor.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/data/RedisStringCommandsFunctionExecutor.java
@@ -27,8 +27,7 @@ public class RedisStringCommandsFunctionExecutor extends RedisDataCommandsFuncti
implements
RedisStringCommands {
- public RedisStringCommandsFunctionExecutor(
- CommandHelper helper) {
+ public RedisStringCommandsFunctionExecutor(CommandHelper helper) {
super(helper);
}
@@ -41,26 +40,24 @@ public class RedisStringCommandsFunctionExecutor extends RedisDataCommandsFuncti
}
@Override
- public long append(RedisKey key, ByteArrayWrapper valueToAppend) {
+ public long append(RedisKey key, byte[] valueToAppend) {
return stripedExecute(key,
- () -> getRedisString(key, false)
- .append(valueToAppend, getRegion(), key));
+ () -> getRedisString(key, false).append(getRegion(), key, valueToAppend));
}
@Override
- public ByteArrayWrapper get(RedisKey key) {
+ public byte[] get(RedisKey key) {
return stripedExecute(key, () -> getRedisString(key, true).get());
}
@Override
- public ByteArrayWrapper mget(RedisKey key) {
+ public byte[] mget(RedisKey key) {
return stripedExecute(key, () -> getRedisStringIgnoringType(key, true).get());
}
@Override
- public boolean set(RedisKey key, ByteArrayWrapper value, SetOptions options) {
- return stripedExecute(key, () -> NULL_REDIS_STRING
- .set(helper, key, value, options));
+ public boolean set(RedisKey key, byte[] value, SetOptions options) {
+ return stripedExecute(key, () -> NULL_REDIS_STRING.set(helper, key, value, options));
}
@Override
@@ -74,9 +71,8 @@ public class RedisStringCommandsFunctionExecutor extends RedisDataCommandsFuncti
}
@Override
- public ByteArrayWrapper getset(RedisKey key, ByteArrayWrapper value) {
- return stripedExecute(key,
- () -> getRedisString(key, true).getset(getRegion(), key, value));
+ public byte[] getset(RedisKey key, byte[] value) {
+ return stripedExecute(key, () -> getRedisString(key, true).getset(getRegion(), key, value));
}
@Override
@@ -88,13 +84,11 @@ public class RedisStringCommandsFunctionExecutor extends RedisDataCommandsFuncti
@Override
public BigDecimal incrbyfloat(RedisKey key, BigDecimal increment) {
return stripedExecute(key,
- () -> getRedisString(key, false)
- .incrbyfloat(getRegion(), key, increment));
+ () -> getRedisString(key, false).incrbyfloat(getRegion(), key, increment));
}
@Override
- public int bitop(String operation, RedisKey key,
- List<RedisKey> sources) {
+ public int bitop(String operation, RedisKey key, List<RedisKey> sources) {
return NULL_REDIS_STRING.bitop(helper, operation, key, sources);
}
@@ -105,22 +99,19 @@ public class RedisStringCommandsFunctionExecutor extends RedisDataCommandsFuncti
}
@Override
- public ByteArrayWrapper getrange(RedisKey key, long start, long end) {
+ public byte[] getrange(RedisKey key, long start, long end) {
return stripedExecute(key, () -> getRedisString(key, true).getrange(start, end));
}
@Override
public int setrange(RedisKey key, int offset, byte[] value) {
return stripedExecute(key,
- () -> getRedisString(key, false)
- .setrange(getRegion(), key, offset, value));
+ () -> getRedisString(key, false).setrange(getRegion(), key, offset, value));
}
@Override
public int bitpos(RedisKey key, int bit, int start, Integer end) {
- return stripedExecute(key,
- () -> getRedisString(key, true)
- .bitpos(getRegion(), key, bit, start, end));
+ return stripedExecute(key, () -> getRedisString(key, true).bitpos(bit, start, end));
}
@Override
@@ -148,8 +139,7 @@ public class RedisStringCommandsFunctionExecutor extends RedisDataCommandsFuncti
int byteIndex = (int) (offset / 8);
byte bitIndex = (byte) (offset % 8);
return stripedExecute(key,
- () -> getRedisString(key, false)
- .setbit(getRegion(), key, value, byteIndex, bitIndex));
+ () -> getRedisString(key, false).setbit(getRegion(), key, value, byteIndex, bitIndex));
}
}
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/CommandFunction.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/CommandFunction.java
index c3bae2e..aab3c59 100644
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/CommandFunction.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/CommandFunction.java
@@ -107,7 +107,7 @@ public class CommandFunction extends SingleResultRedisFunction {
case INTERNALPTTL:
return keyCommands.internalPttl(key);
case APPEND: {
- ByteArrayWrapper valueToAdd = (ByteArrayWrapper) args[1];
+ byte[] valueToAdd = (byte[]) args[1];
return stringCommands.append(key, valueToAdd);
}
case GET:
@@ -117,12 +117,12 @@ public class CommandFunction extends SingleResultRedisFunction {
case STRLEN:
return stringCommands.strlen(key);
case SET: {
- ByteArrayWrapper value = (ByteArrayWrapper) args[1];
+ byte[] value = (byte[]) args[1];
SetOptions options = (SetOptions) args[2];
return stringCommands.set(key, value, options);
}
case GETSET: {
- ByteArrayWrapper value = (ByteArrayWrapper) args[1];
+ byte[] value = (byte[]) args[1];
return stringCommands.getset(key, value);
}
case GETRANGE: {
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/AppendExecutor.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/AppendExecutor.java
index 2cc14eb..ef328cb 100755
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/AppendExecutor.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/AppendExecutor.java
@@ -17,7 +17,6 @@ package org.apache.geode.redis.internal.executor.string;
import java.util.List;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.executor.RedisResponse;
import org.apache.geode.redis.internal.netty.Command;
@@ -28,14 +27,12 @@ public class AppendExecutor extends StringExecutor {
private static final int VALUE_INDEX = 2;
@Override
- public RedisResponse executeCommand(Command command,
- ExecutionHandlerContext context) {
+ public RedisResponse executeCommand(Command command, ExecutionHandlerContext context) {
List<byte[]> commandElems = command.getProcessedCommand();
RedisKey key = command.getKey();
byte[] bytesToAppend = commandElems.get(VALUE_INDEX);
- ByteArrayWrapper valueToAppend = new ByteArrayWrapper(bytesToAppend);
- long returnValue = getRedisStringCommands(context).append(key, valueToAppend);
+ long returnValue = getRedisStringCommands(context).append(key, bytesToAppend);
return RedisResponse.integer(returnValue);
}
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetExecutor.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetExecutor.java
index 5b60d90..a2c8bba 100755
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetExecutor.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetExecutor.java
@@ -14,7 +14,6 @@
*/
package org.apache.geode.redis.internal.executor.string;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.executor.RedisResponse;
import org.apache.geode.redis.internal.netty.Command;
@@ -23,12 +22,11 @@ import org.apache.geode.redis.internal.netty.ExecutionHandlerContext;
public class GetExecutor extends StringExecutor {
@Override
- public RedisResponse executeCommand(Command command,
- ExecutionHandlerContext context) {
+ public RedisResponse executeCommand(Command command, ExecutionHandlerContext context) {
RedisKey key = command.getKey();
RedisStringCommands redisStringCommands = getRedisStringCommands(context);
- ByteArrayWrapper result = redisStringCommands.get(key);
+ byte[] result = redisStringCommands.get(key);
return respondBulkStrings(result);
}
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetRangeExecutor.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetRangeExecutor.java
index 605904b..263fe68 100755
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetRangeExecutor.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetRangeExecutor.java
@@ -18,7 +18,6 @@ import static org.apache.geode.redis.internal.RedisConstants.ERROR_NOT_INTEGER;
import java.util.List;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.executor.RedisResponse;
import org.apache.geode.redis.internal.netty.Coder;
@@ -49,11 +48,11 @@ public class GetRangeExecutor extends StringExecutor {
RedisStringCommands stringCommands = getRedisStringCommands(context);
RedisKey key = command.getKey();
- ByteArrayWrapper returnRange = stringCommands.getrange(key, start, end);
+ byte[] returnRange = stringCommands.getrange(key, start, end);
if (returnRange == null) {
return RedisResponse.nil();
- } else if (returnRange.length() == 0) {
+ } else if (returnRange.length == 0) {
return RedisResponse.emptyString();
} else {
return respondBulkStrings(returnRange);
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetSetExecutor.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetSetExecutor.java
index c26d33d..ec3ffb3 100755
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetSetExecutor.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetSetExecutor.java
@@ -17,7 +17,6 @@ package org.apache.geode.redis.internal.executor.string;
import java.util.List;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.executor.RedisResponse;
import org.apache.geode.redis.internal.netty.Command;
@@ -33,10 +32,9 @@ public class GetSetExecutor extends StringExecutor {
RedisKey key = command.getKey();
byte[] newCharValue = commandElems.get(VALUE_INDEX);
- ByteArrayWrapper newValueWrapper = new ByteArrayWrapper(newCharValue);
RedisStringCommands stringCommands = getRedisStringCommands(context);
- ByteArrayWrapper oldValueWrapper = stringCommands.getset(key, newValueWrapper);
+ byte[] oldValueWrapper = stringCommands.getset(key, newCharValue);
return respondBulkStrings(oldValueWrapper);
}
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MGetExecutor.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MGetExecutor.java
index 2447241..d65a0f76 100755
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MGetExecutor.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MGetExecutor.java
@@ -18,7 +18,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.executor.RedisResponse;
import org.apache.geode.redis.internal.netty.Command;
@@ -31,7 +30,7 @@ public class MGetExecutor extends StringExecutor {
List<byte[]> commandElems = command.getProcessedCommand();
RedisStringCommands stringCommands = getRedisStringCommands(context);
- Collection<ByteArrayWrapper> values = new ArrayList<>();
+ Collection<byte[]> values = new ArrayList<>();
for (int i = 1; i < commandElems.size(); i++) {
byte[] keyArray = commandElems.get(i);
RedisKey key = new RedisKey(keyArray);
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MSetExecutor.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MSetExecutor.java
index 98ce50a..26298a5 100755
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MSetExecutor.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MSetExecutor.java
@@ -16,7 +16,6 @@ package org.apache.geode.redis.internal.executor.string;
import java.util.List;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.executor.RedisResponse;
import org.apache.geode.redis.internal.netty.Command;
@@ -37,8 +36,7 @@ public class MSetExecutor extends StringExecutor {
byte[] keyArray = commandElems.get(i);
RedisKey key = new RedisKey(keyArray);
byte[] valueArray = commandElems.get(i + 1);
- ByteArrayWrapper value = new ByteArrayWrapper(valueArray);
- stringCommands.set(key, value, null);
+ stringCommands.set(key, valueArray, null);
}
return RedisResponse.string(SUCCESS);
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MSetNXExecutor.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MSetNXExecutor.java
index d3ac56a..c289662 100755
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MSetNXExecutor.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/MSetNXExecutor.java
@@ -17,7 +17,6 @@ package org.apache.geode.redis.internal.executor.string;
import java.util.List;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.executor.RedisResponse;
import org.apache.geode.redis.internal.executor.key.RedisKeyCommands;
@@ -51,8 +50,7 @@ public class MSetNXExecutor extends StringExecutor {
byte[] keyArray = commandElems.get(i);
RedisKey key = new RedisKey(keyArray);
byte[] valueArray = commandElems.get(i + 1);
- ByteArrayWrapper value = new ByteArrayWrapper(valueArray);
- stringCommands.set(key, value, null);
+ stringCommands.set(key, valueArray, null);
}
return RedisResponse.integer(SET);
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommands.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommands.java
index f4f6f5c..8d4b94f 100644
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommands.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommands.java
@@ -17,27 +17,26 @@ package org.apache.geode.redis.internal.executor.string;
import java.math.BigDecimal;
import java.util.List;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisKey;
public interface RedisStringCommands {
- long append(RedisKey key, ByteArrayWrapper valueToAppend);
+ long append(RedisKey key, byte[] valueToAppend);
- ByteArrayWrapper get(RedisKey key);
+ byte[] get(RedisKey key);
- boolean set(RedisKey key, ByteArrayWrapper value, SetOptions options);
+ boolean set(RedisKey key, byte[] value, SetOptions options);
long incr(RedisKey key);
long decr(RedisKey key);
- ByteArrayWrapper getset(RedisKey key, ByteArrayWrapper value);
+ byte[] getset(RedisKey key, byte[] value);
long incrby(RedisKey key, long increment);
long decrby(RedisKey key, long decrement);
- ByteArrayWrapper getrange(RedisKey key, long start, long end);
+ byte[] getrange(RedisKey key, long start, long end);
long bitcount(RedisKey key, int start, int end);
@@ -57,5 +56,5 @@ public interface RedisStringCommands {
int setrange(RedisKey key, int offset, byte[] value);
- ByteArrayWrapper mget(RedisKey key);
+ byte[] mget(RedisKey key);
}
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommandsFunctionInvoker.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommandsFunctionInvoker.java
index 79b6cd2..9d4b2ec 100644
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommandsFunctionInvoker.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommandsFunctionInvoker.java
@@ -37,7 +37,6 @@ import java.math.BigDecimal;
import java.util.List;
import org.apache.geode.cache.Region;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisData;
import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.executor.RedisCommandsFunctionInvoker;
@@ -55,17 +54,17 @@ public class RedisStringCommandsFunctionInvoker extends RedisCommandsFunctionInv
}
@Override
- public long append(RedisKey key, ByteArrayWrapper valueToAppend) {
+ public long append(RedisKey key, byte[] valueToAppend) {
return invokeCommandFunction(key, APPEND, valueToAppend);
}
@Override
- public ByteArrayWrapper get(RedisKey key) {
+ public byte[] get(RedisKey key) {
return invokeCommandFunction(key, GET);
}
@Override
- public boolean set(RedisKey key, ByteArrayWrapper value, SetOptions options) {
+ public boolean set(RedisKey key, byte[] value, SetOptions options) {
return invokeCommandFunction(key, SET, value, options);
}
@@ -80,7 +79,7 @@ public class RedisStringCommandsFunctionInvoker extends RedisCommandsFunctionInv
}
@Override
- public ByteArrayWrapper getset(RedisKey key, ByteArrayWrapper value) {
+ public byte[] getset(RedisKey key, byte[] value) {
return invokeCommandFunction(key, GETSET, value);
}
@@ -95,7 +94,7 @@ public class RedisStringCommandsFunctionInvoker extends RedisCommandsFunctionInv
}
@Override
- public ByteArrayWrapper getrange(RedisKey key, long start, long end) {
+ public byte[] getrange(RedisKey key, long start, long end) {
return invokeCommandFunction(key, GETRANGE, start, end);
}
@@ -145,7 +144,7 @@ public class RedisStringCommandsFunctionInvoker extends RedisCommandsFunctionInv
}
@Override
- public ByteArrayWrapper mget(RedisKey key) {
+ public byte[] mget(RedisKey key) {
return invokeCommandFunction(key, MGET);
}
}
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetEXExecutor.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetEXExecutor.java
index c4d2c53..a466ac1 100755
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetEXExecutor.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetEXExecutor.java
@@ -19,7 +19,6 @@ import static org.apache.geode.redis.internal.executor.string.SetOptions.Exists.
import java.util.List;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.executor.RedisResponse;
import org.apache.geode.redis.internal.netty.Coder;
@@ -64,7 +63,7 @@ public class SetEXExecutor extends StringExecutor {
}
SetOptions setOptions = new SetOptions(NONE, expiration, false);
- stringCommands.set(key, new ByteArrayWrapper(value), setOptions);
+ stringCommands.set(key, value, setOptions);
return RedisResponse.string(SUCCESS);
}
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetExecutor.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetExecutor.java
index a2b71fa..8aa9474 100755
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetExecutor.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetExecutor.java
@@ -24,7 +24,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.executor.RedisResponse;
import org.apache.geode.redis.internal.netty.Coder;
@@ -33,16 +32,15 @@ import org.apache.geode.redis.internal.netty.ExecutionHandlerContext;
public class SetExecutor extends StringExecutor {
+ private static final int VALUE_INDEX = 2;
private static final String SUCCESS = "OK";
@Override
- public RedisResponse executeCommand(Command command,
- ExecutionHandlerContext context) {
+ public RedisResponse executeCommand(Command command, ExecutionHandlerContext context) {
RedisKey keyToSet = command.getKey();
List<byte[]> commandElementsBytes = command.getProcessedCommand();
List<byte[]> optionalParameterBytes = getOptionalParameters(commandElementsBytes);
- ByteArrayWrapper valueToSet = getValueToSet(commandElementsBytes);
RedisStringCommands redisStringCommands = getRedisStringCommands(context);
SetOptions setOptions;
@@ -52,15 +50,15 @@ public class SetExecutor extends StringExecutor {
return RedisResponse.error(ex.getMessage());
}
- return doSet(keyToSet, valueToSet, redisStringCommands, setOptions);
+ return doSet(keyToSet, commandElementsBytes.get(VALUE_INDEX), redisStringCommands, setOptions);
}
private List<byte[]> getOptionalParameters(List<byte[]> commandElementsBytes) {
return commandElementsBytes.subList(3, commandElementsBytes.size());
}
- private RedisResponse doSet(RedisKey key, ByteArrayWrapper value,
- RedisStringCommands redisStringCommands, SetOptions setOptions) {
+ private RedisResponse doSet(RedisKey key, byte[] value, RedisStringCommands redisStringCommands,
+ SetOptions setOptions) {
boolean setCompletedSuccessfully = redisStringCommands.set(key, value, setOptions);
@@ -71,11 +69,6 @@ public class SetExecutor extends StringExecutor {
}
}
- private ByteArrayWrapper getValueToSet(List<byte[]> commandElems) {
- byte[] value = commandElems.get(2);
- return new ByteArrayWrapper(value);
- }
-
private SetOptions parseOptionalParameters(List<byte[]> optionalParameterBytes)
throws IllegalArgumentException {
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetNXExecutor.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetNXExecutor.java
index 8aa6fae..68abf53 100755
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetNXExecutor.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetNXExecutor.java
@@ -18,7 +18,6 @@ import static org.apache.geode.redis.internal.executor.string.SetOptions.Exists.
import java.util.List;
-import org.apache.geode.redis.internal.data.ByteArrayWrapper;
import org.apache.geode.redis.internal.data.RedisKey;
import org.apache.geode.redis.internal.executor.RedisResponse;
import org.apache.geode.redis.internal.netty.Command;
@@ -32,12 +31,11 @@ public class SetNXExecutor extends StringExecutor {
public RedisResponse executeCommand(Command command, ExecutionHandlerContext context) {
List<byte[]> commandElems = command.getProcessedCommand();
RedisKey key = command.getKey();
- ByteArrayWrapper value = new ByteArrayWrapper(commandElems.get(VALUE_INDEX));
RedisStringCommands stringCommands = getRedisStringCommands(context);
SetOptions setOptions = new SetOptions(NX, 0L, false);
- boolean result = stringCommands.set(key, value, setOptions);
+ boolean result = stringCommands.set(key, commandElems.get(VALUE_INDEX), setOptions);
return RedisResponse.integer(result);
}
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetOptions.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetOptions.java
index b9667ff..b4b4f42 100644
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetOptions.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/executor/string/SetOptions.java
@@ -76,8 +76,7 @@ public class SetOptions implements DataSerializableFixedID {
}
@Override
- public void fromData(DataInput in, DeserializationContext context)
- throws IOException, ClassNotFoundException {
+ public void fromData(DataInput in, DeserializationContext context) throws IOException {
exists = DataSerializer.readEnum(SetOptions.Exists.class, in);
expirationMillis = in.readLong();
keepTTL = in.readBoolean();
@@ -99,6 +98,6 @@ public class SetOptions implements DataSerializableFixedID {
/**
* Only set if key already exists
*/
- XX;
+ XX
}
}
diff --git a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/netty/Coder.java b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/netty/Coder.java
index 14a31d5..326aab4 100644
--- a/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/netty/Coder.java
+++ b/geode-apis-compatible-with-redis/src/main/java/org/apache/geode/redis/internal/netty/Coder.java
@@ -171,20 +171,12 @@ public class Coder {
return buffer;
}
- private static void writeCollectionOrString(ByteBuf buffer, Object next)
- throws CoderException {
- ByteBuf tmp = null;
- try {
- if (next instanceof Collection) {
- Collection<?> nextItems = (Collection<?>) next;
- getArrayResponse(buffer, nextItems);
- } else {
- getBulkStringResponse(buffer, next);
- }
- } finally {
- if (tmp != null) {
- tmp.release();
- }
+ private static void writeCollectionOrString(ByteBuf buffer, Object next) throws CoderException {
+ if (next instanceof Collection) {
+ Collection<?> nextItems = (Collection<?>) next;
+ getArrayResponse(buffer, nextItems);
+ } else {
+ getBulkStringResponse(buffer, next);
}
}
diff --git a/geode-apis-compatible-with-redis/src/test/java/org/apache/geode/redis/internal/data/RedisStringTest.java b/geode-apis-compatible-with-redis/src/test/java/org/apache/geode/redis/internal/data/RedisStringTest.java
index 50481bb..79d9133 100644
--- a/geode-apis-compatible-with-redis/src/test/java/org/apache/geode/redis/internal/data/RedisStringTest.java
+++ b/geode-apis-compatible-with-redis/src/test/java/org/apache/geode/redis/internal/data/RedisStringTest.java
@@ -17,6 +17,7 @@
package org.apache.geode.redis.internal.data;
import static org.apache.geode.redis.internal.data.RedisString.BASE_REDIS_STRING_OVERHEAD;
+import static org.apache.geode.util.internal.UncheckedUtils.uncheckedCast;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
@@ -26,6 +27,7 @@ import java.io.IOException;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
+import org.apache.commons.lang3.StringUtils;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -43,9 +45,6 @@ public class RedisStringTest {
@BeforeClass
public static void beforeClass() {
- InternalDataSerializer
- .getDSFIDSerializer()
- .registerDSFID(DataSerializableFixedID.REDIS_BYTE_ARRAY_WRAPPER, ByteArrayWrapper.class);
InternalDataSerializer.getDSFIDSerializer().registerDSFID(
DataSerializableFixedID.REDIS_STRING_ID,
RedisString.class);
@@ -53,75 +52,78 @@ public class RedisStringTest {
@Test
public void constructorSetsValue() {
- ByteArrayWrapper byteArrayWrapper = new ByteArrayWrapper(new byte[] {0, 1, 2});
- RedisString string = new RedisString(byteArrayWrapper);
- ByteArrayWrapper returnedByteArrayWrapper = string.get();
- assertThat(returnedByteArrayWrapper).isNotNull();
- assertThat(returnedByteArrayWrapper.value).isEqualTo(byteArrayWrapper.value);
+ byte[] bytes = {0, 1, 2};
+ RedisString string = new RedisString(bytes);
+ byte[] returnedBytes = string.get();
+ assertThat(returnedBytes).isNotNull();
+ assertThat(returnedBytes).isEqualTo(bytes);
}
@Test
public void setSetsValue() {
RedisString string = new RedisString();
- string.set(new ByteArrayWrapper(new byte[] {0, 1, 2}));
- ByteArrayWrapper returnedByteArrayWrapper = string.get();
- assertThat(returnedByteArrayWrapper).isNotNull();
- assertThat(returnedByteArrayWrapper.value)
- .isEqualTo(new ByteArrayWrapper(new byte[] {0, 1, 2}).value);
+ byte[] bytes = {0, 1, 2};
+ string.set(bytes);
+ byte[] returnedBytes = string.get();
+ assertThat(returnedBytes).isNotNull();
+ assertThat(returnedBytes).isEqualTo(bytes);
}
@Test
public void getReturnsSetValue() {
- RedisString string = new RedisString(new ByteArrayWrapper(new byte[] {0, 1}));
- ByteArrayWrapper returnedByteArrayWrapper = string.get();
- assertThat(returnedByteArrayWrapper).isNotNull();
- assertThat(returnedByteArrayWrapper.value)
- .isEqualTo(new ByteArrayWrapper(new byte[] {0, 1}).value);
+ byte[] bytes = {0, 1};
+ RedisString string = new RedisString(bytes);
+ byte[] returnedBytes = string.get();
+ assertThat(returnedBytes).isNotNull();
+ assertThat(returnedBytes).isEqualTo(bytes);
}
@Test
public void appendResizesByteArray() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisString redisString = new RedisString(new ByteArrayWrapper(new byte[] {0, 1}));
- ByteArrayWrapper part2 = new ByteArrayWrapper(new byte[] {2, 3, 4, 5});
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ RedisString redisString = new RedisString(new byte[] {0, 1});
int redisStringSize = redisString.strlen();
- int part2Size = part2.length();
- int appendedStringSize = redisString.append(part2, region, null);
- assertThat(appendedStringSize).isEqualTo(redisStringSize + part2Size);
+ byte[] bytesToAppend = {2, 3, 4, 5};
+ int appendedSize = bytesToAppend.length;
+ int appendedStringSize = redisString.append(region, null, bytesToAppend);
+ assertThat(appendedStringSize).isEqualTo(redisStringSize + appendedSize);
}
@Test
public void appendStoresStableDelta() throws IOException {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisString o1 = new RedisString(new ByteArrayWrapper(new byte[] {0, 1}));
- ByteArrayWrapper part2 = new ByteArrayWrapper(new byte[] {2, 3});
- o1.append(part2, region, null);
- assertThat(o1.hasDelta()).isTrue();
- assertThat(o1.get()).isEqualTo(new ByteArrayWrapper(new byte[] {0, 1, 2, 3}));
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] baseBytes = {0, 1};
+ byte[] bytesToAppend = {2, 3};
+ byte[] baseAndAppendedBytes = {0, 1, 2, 3};
+
+ RedisString stringOne = new RedisString(baseBytes);
+ stringOne.append(region, null, bytesToAppend);
+ assertThat(stringOne.hasDelta()).isTrue();
+ assertThat(stringOne.get()).isEqualTo(baseAndAppendedBytes);
HeapDataOutputStream out = new HeapDataOutputStream(100);
- o1.toDelta(out);
- assertThat(o1.hasDelta()).isFalse();
+ stringOne.toDelta(out);
+ assertThat(stringOne.hasDelta()).isFalse();
ByteArrayDataInput in = new ByteArrayDataInput(out.toByteArray());
- RedisString o2 = new RedisString(new ByteArrayWrapper(new byte[] {0, 1}));
- assertThat(o2).isNotEqualTo(o1);
- o2.fromDelta(in);
- assertThat(o2.get()).isEqualTo(new ByteArrayWrapper(new byte[] {0, 1, 2, 3}));
- assertThat(o2).isEqualTo(o1);
+ RedisString stringTwo = new RedisString(baseBytes);
+ assertThat(stringTwo).isNotEqualTo(stringOne);
+ stringTwo.fromDelta(in);
+ assertThat(stringTwo.get()).isEqualTo(baseAndAppendedBytes);
+ assertThat(stringTwo).isEqualTo(stringOne);
}
@Test
public void confirmSerializationIsStable() throws IOException, ClassNotFoundException {
- RedisString o1 = new RedisString(new ByteArrayWrapper(new byte[] {0, 1, 2, 3}));
- o1.setExpirationTimestampNoDelta(1000);
+ RedisString stringOne = new RedisString(new byte[] {0, 1, 2, 3});
+ int expirationTimestamp = 1000;
+ stringOne.setExpirationTimestampNoDelta(expirationTimestamp);
HeapDataOutputStream outputStream = new HeapDataOutputStream(100);
- DataSerializer.writeObject(o1, outputStream);
+ DataSerializer.writeObject(stringOne, outputStream);
ByteArrayDataInput dataInput = new ByteArrayDataInput(outputStream.toByteArray());
- RedisString o2 = DataSerializer.readObject(dataInput);
- assertThat(o2).isEqualTo(o1);
+ RedisString stringTwo = DataSerializer.readObject(dataInput);
+ assertThat(stringTwo).isEqualTo(stringOne);
+ assertThat(stringTwo.getExpirationTimestamp())
+ .isEqualTo(stringOne.getExpirationTimestamp())
+ .isEqualTo(expirationTimestamp);
}
@Test
@@ -134,225 +136,191 @@ public class RedisStringTest {
@Test
public void incrThrowsArithmeticErrorWhenNotALong() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(new byte[] {'1', '0', ' ', '1'});
- RedisString string = new RedisString(byteArrayWrapper);
- assertThatThrownBy(() -> string.incr(region, byteArrayWrapper))
- .isInstanceOf(NumberFormatException.class);
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = "10 1".getBytes();
+ RedisString string = new RedisString(bytes);
+ assertThatThrownBy(() -> string.incr(region, null)).isInstanceOf(NumberFormatException.class);
}
@Test
public void incrErrorsWhenValueOverflows() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(
- // max value for signed long
- new byte[] {'9', '2', '2', '3', '3', '7', '2', '0', '3', '6', '8', '5', '4', '7', '7', '5',
- '8', '0', '7'});
- RedisString string = new RedisString(byteArrayWrapper);
- assertThatThrownBy(() -> string.incr(region, byteArrayWrapper))
- .isInstanceOf(ArithmeticException.class);
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = String.valueOf(Long.MAX_VALUE).getBytes();
+ RedisString string = new RedisString(bytes);
+ assertThatThrownBy(() -> string.incr(region, null)).isInstanceOf(ArithmeticException.class);
}
@Test
public void incrIncrementsValueAtGivenKey() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(new byte[] {'1', '0'});
- RedisString string = new RedisString(byteArrayWrapper);
- string.incr(region, byteArrayWrapper);
- assertThat(string.get().toString()).isEqualTo("11");
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = "10".getBytes();
+ RedisString string = new RedisString(bytes);
+ string.incr(region, null);
+ assertThat(string.get()).isEqualTo("11".getBytes());
}
@Test
public void incrbyThrowsNumberFormatExceptionWhenNotALong() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(new byte[] {'1', '0', ' ', '1'});
- RedisString string = new RedisString(byteArrayWrapper);
- assertThatThrownBy(() -> string.incrby(region, byteArrayWrapper, 2L))
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = "10 1".getBytes();
+ RedisString string = new RedisString(bytes);
+ assertThatThrownBy(() -> string.incrby(region, null, 2L))
.isInstanceOf(NumberFormatException.class);
}
@Test
public void incrbyErrorsWhenValueOverflows() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(
- // max value for signed long
- new byte[] {'9', '2', '2', '3', '3', '7', '2', '0', '3', '6', '8', '5', '4', '7', '7', '5',
- '8', '0', '7'});
- RedisString string = new RedisString(byteArrayWrapper);
- assertThatThrownBy(() -> string.incrby(region, byteArrayWrapper, 2L))
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = String.valueOf(Long.MAX_VALUE).getBytes();
+ RedisString string = new RedisString(bytes);
+ assertThatThrownBy(() -> string.incrby(region, null, 2L))
.isInstanceOf(ArithmeticException.class);
}
@Test
public void incrbyIncrementsValueByGivenLong() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(new byte[] {'1', '0'});
- RedisString string = new RedisString(byteArrayWrapper);
- string.incrby(region, byteArrayWrapper, 2L);
- assertThat(string.get().toString()).isEqualTo("12");
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = "10".getBytes();
+ RedisString string = new RedisString(bytes);
+ string.incrby(region, null, 2L);
+ assertThat(string.get()).isEqualTo("12".getBytes());
}
@Test
public void incrbyfloatThrowsArithmeticErrorWhenNotADouble() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(new byte[] {'1', '0', ' ', '1'});
- RedisString string = new RedisString(byteArrayWrapper);
- assertThatThrownBy(() -> string.incrbyfloat(region, byteArrayWrapper, new BigDecimal("1.1")))
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = "10 1".getBytes();
+ RedisString string = new RedisString(bytes);
+ assertThatThrownBy(() -> string.incrbyfloat(region, null, new BigDecimal("1.1")))
.isInstanceOf(NumberFormatException.class);
}
@Test
public void incrbyfloatIncrementsValueByGivenFloat() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(new byte[] {'1', '0'});
- RedisString string = new RedisString(byteArrayWrapper);
- string.incrbyfloat(region, byteArrayWrapper, new BigDecimal("2.20"));
- assertThat(string.get().toString()).isEqualTo("12.20");
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = "10".getBytes();
+ RedisString string = new RedisString(bytes);
+ string.incrbyfloat(region, null, new BigDecimal("2.20"));
+ assertThat(string.get()).isEqualTo("12.20".getBytes());
}
@Test
public void decrThrowsNumberFormatExceptionWhenNotALong() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(new byte[] {0});
- RedisString string = new RedisString(byteArrayWrapper);
- assertThatThrownBy(() -> string.decr(region, byteArrayWrapper))
- .isInstanceOf(NumberFormatException.class);
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = {0};
+ RedisString string = new RedisString(bytes);
+ assertThatThrownBy(() -> string.decr(region, null)).isInstanceOf(NumberFormatException.class);
}
@Test
public void decrThrowsArithmeticExceptionWhenDecrementingMin() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(
- new byte[] {'-', '9', '2', '2', '3', '3', '7', '2', '0', '3', '6', '8', '5', '4', '7', '7',
- '5',
- '8', '0', '8'});
- RedisString string = new RedisString(byteArrayWrapper);
- assertThatThrownBy(() -> string.decr(region, byteArrayWrapper))
- .isInstanceOf(ArithmeticException.class);
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = String.valueOf(Long.MIN_VALUE).getBytes();
+ RedisString string = new RedisString(bytes);
+ assertThatThrownBy(() -> string.decr(region, null)).isInstanceOf(ArithmeticException.class);
}
@Test
public void decrDecrementsValue() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(new byte[] {'1', '0'});
- RedisString string = new RedisString(byteArrayWrapper);
- string.decr(region, byteArrayWrapper);
- assertThat(string.get().toString()).isEqualTo("9");
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = "10".getBytes();
+ RedisString string = new RedisString(bytes);
+ string.decr(region, null);
+ assertThat(string.get()).isEqualTo("9".getBytes());
}
@Test
public void decrbyThrowsNumberFormatExceptionWhenNotALong() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(new byte[] {1});
- RedisString string = new RedisString(byteArrayWrapper);
- assertThatThrownBy(() -> string.decrby(region, byteArrayWrapper, 2))
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = {1};
+ RedisString string = new RedisString(bytes);
+ assertThatThrownBy(() -> string.decrby(region, null, 2))
.isInstanceOf(NumberFormatException.class);
}
@Test
public void decrbyThrowsArithmeticExceptionWhenDecrementingMin() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(
- new byte[] {'-', '9', '2', '2', '3', '3', '7', '2', '0', '3', '6', '8', '5', '4', '7', '7',
- '5',
- '8', '0', '7'});
- RedisString string = new RedisString(byteArrayWrapper);
- assertThatThrownBy(() -> string.decrby(region, byteArrayWrapper, 2))
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = String.valueOf(Long.MIN_VALUE).getBytes();
+ RedisString string = new RedisString(bytes);
+ assertThatThrownBy(() -> string.decrby(region, null, 2))
.isInstanceOf(ArithmeticException.class);
}
@Test
public void decrbyDecrementsValue() {
- // allows unchecked cast of mock to Region<RedisKey, RedisData>
- @SuppressWarnings("unchecked")
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisKey byteArrayWrapper = new RedisKey(new byte[] {'1', '0'});
- RedisString string = new RedisString(byteArrayWrapper);
- string.decrby(region, byteArrayWrapper, 2);
- assertThat(string.get().toString()).isEqualTo("8");
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = "10".getBytes();
+ RedisString string = new RedisString(bytes);
+ string.decrby(region, null, 2);
+ assertThat(string.get()).isEqualTo("8".getBytes());
}
@Test
public void strlenReturnsStringLength() {
- RedisString string = new RedisString(new ByteArrayWrapper(new byte[] {1, 2, 3, 4}));
- assertThat(string.strlen()).isEqualTo(4);
+ byte[] bytes = {1, 2, 3, 4};
+ RedisString string = new RedisString(bytes);
+ assertThat(string.strlen()).isEqualTo(bytes.length);
}
@Test
public void strlenReturnsLengthOfEmptyString() {
- RedisString string = new RedisString(new ByteArrayWrapper(new byte[] {}));
+ RedisString string = new RedisString(new byte[] {});
assertThat(string.strlen()).isEqualTo(0);
}
@Test
public void equals_returnsFalse_givenDifferentExpirationTimes() {
- RedisString o1 = new RedisString(new ByteArrayWrapper(new byte[] {0, 1, 2, 3}));
- o1.setExpirationTimestampNoDelta(1000);
- RedisString o2 = new RedisString(new ByteArrayWrapper(new byte[] {0, 1, 2, 3}));
- o2.setExpirationTimestampNoDelta(999);
- assertThat(o1).isNotEqualTo(o2);
+ byte[] bytes = {0, 1, 2, 3};
+ RedisString stringOne = new RedisString(bytes);
+ stringOne.setExpirationTimestampNoDelta(1000);
+ RedisString stringTwo = new RedisString(bytes);
+ stringTwo.setExpirationTimestampNoDelta(999);
+ assertThat(stringOne).isNotEqualTo(stringTwo);
}
@Test
public void equals_returnsFalse_givenDifferentValueBytes() {
- RedisString o1 = new RedisString(new ByteArrayWrapper(new byte[] {0, 1, 2, 3}));
- o1.setExpirationTimestampNoDelta(1000);
- RedisString o2 = new RedisString(new ByteArrayWrapper(new byte[] {0, 1, 2, 2}));
- o2.setExpirationTimestampNoDelta(1000);
- assertThat(o1).isNotEqualTo(o2);
+ int expirationTimestamp = 1000;
+ RedisString stringOne = new RedisString(new byte[] {0, 1, 2, 3});
+ stringOne.setExpirationTimestampNoDelta(expirationTimestamp);
+ RedisString stringTwo = new RedisString(new byte[] {0, 1, 2, 2});
+ stringTwo.setExpirationTimestampNoDelta(expirationTimestamp);
+ assertThat(stringOne).isNotEqualTo(stringTwo);
}
@Test
public void equals_returnsTrue_givenEqualValueBytesAndExpiration() {
- RedisString o1 = new RedisString(new ByteArrayWrapper(new byte[] {0, 1, 2, 3}));
- o1.setExpirationTimestampNoDelta(1000);
- RedisString o2 = new RedisString(new ByteArrayWrapper(new byte[] {0, 1, 2, 3}));
- o2.setExpirationTimestampNoDelta(1000);
- assertThat(o1).isEqualTo(o2);
+ byte[] bytes = {0, 1, 2, 3};
+ int expirationTimestamp = 1000;
+ RedisString stringOne = new RedisString(bytes);
+ stringOne.setExpirationTimestampNoDelta(expirationTimestamp);
+ RedisString stringTwo = new RedisString(bytes);
+ stringTwo.setExpirationTimestampNoDelta(expirationTimestamp);
+ assertThat(stringOne).isEqualTo(stringTwo);
}
-
- @SuppressWarnings("unchecked")
@Test
public void setExpirationTimestamp_stores_delta_that_is_stable() throws IOException {
- Region<RedisKey, RedisData> region = mock(Region.class);
- RedisString o1 = new RedisString(new ByteArrayWrapper(new byte[] {0, 1}));
- o1.setExpirationTimestamp(region, null, 999);
- assertThat(o1.hasDelta()).isTrue();
+ Region<RedisKey, RedisData> region = uncheckedCast(mock(Region.class));
+ byte[] bytes = {0, 1};
+ RedisString stringOne = new RedisString(bytes);
+ stringOne.setExpirationTimestamp(region, null, 999);
+ assertThat(stringOne.hasDelta()).isTrue();
HeapDataOutputStream out = new HeapDataOutputStream(100);
- o1.toDelta(out);
- assertThat(o1.hasDelta()).isFalse();
+ stringOne.toDelta(out);
+ assertThat(stringOne.hasDelta()).isFalse();
ByteArrayDataInput in = new ByteArrayDataInput(out.toByteArray());
- RedisString o2 = new RedisString(new ByteArrayWrapper(new byte[] {0, 1}));
- assertThat(o2).isNotEqualTo(o1);
- o2.fromDelta(in);
- assertThat(o2).isEqualTo(o1);
+ RedisString stringTwo = new RedisString(bytes);
+ assertThat(stringTwo).isNotEqualTo(stringOne);
+ stringTwo.fromDelta(in);
+ assertThat(stringTwo).isEqualTo(stringOne);
+ }
+
+ @Test
+ public void bitposReturnsNegativeOneWhenBitIsNotZeroOrOne() {
+ RedisString string = new RedisString(new byte[] {0, 1});
+ assertThat(string.bitpos(2, 0, 1)).isEqualTo(-1);
}
/************* Size in Bytes Tests *************/
@@ -360,7 +328,7 @@ public class RedisStringTest {
@Test
public void should_calculateSize_equalToROSSize_ofLargeStrings() {
String javaString = makeStringOfSpecifiedSize(10_000);
- RedisString string = new RedisString(new ByteArrayWrapper(javaString.getBytes()));
+ RedisString string = new RedisString(javaString.getBytes());
int actual = string.getSizeInBytes();
int expected = reflectionObjectSizer.sizeof(string);
@@ -373,7 +341,7 @@ public class RedisStringTest {
String javaString;
for (int i = 0; i < 512; i += 8) {
javaString = makeStringOfSpecifiedSize(i);
- RedisString string = new RedisString(new ByteArrayWrapper(javaString.getBytes()));
+ RedisString string = new RedisString(javaString.getBytes());
int expected = reflectionObjectSizer.sizeof(string);
int actual = string.getSizeInBytes();
@@ -386,37 +354,39 @@ public class RedisStringTest {
@Test
public void changingStringValue_toShorterString_shouldDecreaseSizeInBytes() {
String baseString = "baseString";
- RedisString string = new RedisString(new ByteArrayWrapper((baseString + "asdf").getBytes()));
+ String stringToRemove = "asdf";
+ RedisString string = new RedisString((baseString + stringToRemove).getBytes());
int initialSize = string.getSizeInBytes();
- string.set(new ByteArrayWrapper(baseString.getBytes()));
+ string.set(baseString.getBytes());
int finalSize = string.getSizeInBytes();
- assertThat(finalSize).isEqualTo(initialSize - 4);
+ assertThat(finalSize).isEqualTo(initialSize - stringToRemove.length());
}
@Test
public void changingStringValue_toLongerString_shouldIncreaseSizeInBytes() {
String baseString = "baseString";
- RedisString string = new RedisString(new ByteArrayWrapper(baseString.getBytes()));
+ RedisString string = new RedisString(baseString.getBytes());
int initialSize = string.getSizeInBytes();
- string.set(new ByteArrayWrapper((baseString + "asdf").getBytes()));
+ String addedString = "asdf";
+ string.set((baseString + addedString).getBytes());
int finalSize = string.getSizeInBytes();
- assertThat(finalSize).isEqualTo(initialSize + 4);
+ assertThat(finalSize).isEqualTo(initialSize + addedString.length());
}
@Test
public void changingStringValue_toEmptyString_shouldDecreaseSizeInBytes_toBaseSize() {
String baseString = "baseString";
- RedisString string = new RedisString(new ByteArrayWrapper((baseString + "asdf").getBytes()));
+ RedisString string = new RedisString((baseString + "asdf").getBytes());
- string.set(new ByteArrayWrapper("".getBytes()));
+ string.set("".getBytes());
int finalSize = string.getSizeInBytes();
@@ -430,7 +400,7 @@ public class RedisStringTest {
// carefully consider that increase before changing the constant.
@Test
public void overheadConstants_shouldMatchCalculatedValue() {
- RedisString redisString = new RedisString(new ByteArrayWrapper("".getBytes()));
+ RedisString redisString = new RedisString("".getBytes());
int calculatedSize = reflectionObjectSizer.sizeof(redisString);
assertThat(BASE_REDIS_STRING_OVERHEAD).isEqualTo(calculatedSize);
@@ -439,10 +409,6 @@ public class RedisStringTest {
/******* helper methods *******/
private String makeStringOfSpecifiedSize(final int stringSize) {
- StringBuffer sb = new StringBuffer(stringSize);
- for (int i = 0; i < stringSize; i++) {
- sb.append("a");
- }
- return sb.toString();
+ return StringUtils.repeat("a", stringSize);
}
}