use of org.apache.geode.redis.internal.ByteArrayWrapper in project geode by apache.
the class BitCountExecutor method executeCommand.
@Override
public void executeCommand(Command command, ExecutionHandlerContext context) {
List<byte[]> commandElems = command.getProcessedCommand();
Region<ByteArrayWrapper, ByteArrayWrapper> r = context.getRegionProvider().getStringsRegion();
if (commandElems.size() != 2 && commandElems.size() != 4) {
command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.BITCOUNT));
return;
}
ByteArrayWrapper key = command.getKey();
checkAndSetDataType(key, context);
ByteArrayWrapper wrapper = r.get(key);
if (wrapper == null) {
command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), 0));
return;
}
byte[] value = wrapper.toBytes();
long startL = 0;
long endL = value.length - 1;
if (commandElems.size() == 4) {
try {
startL = Coder.bytesToLong(commandElems.get(2));
endL = Coder.bytesToLong(commandElems.get(3));
} catch (NumberFormatException e) {
command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_NOT_INT));
return;
}
}
if (startL > Integer.MAX_VALUE || endL > Integer.MAX_VALUE) {
command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), RedisConstants.ERROR_OUT_OF_RANGE));
return;
}
int start = (int) startL;
int end = (int) endL;
if (start < 0)
start += value.length;
if (end < 0)
end += value.length;
if (start < 0)
start = 0;
if (end < 0)
end = 0;
if (end > value.length - 1)
end = value.length - 1;
if (end < start || start >= value.length) {
command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), 0));
return;
}
long setBits = 0;
for (int j = start; j <= end; j++) // 0xFF keeps same bit sequence as the byte as
setBits += Integer.bitCount(0xFF & value[j]);
// opposed to keeping the same value
command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), setBits));
}
use of org.apache.geode.redis.internal.ByteArrayWrapper in project geode by apache.
the class PopExecutor method executeCommand.
@Override
public void executeCommand(Command command, ExecutionHandlerContext context) {
List<byte[]> commandElems = command.getProcessedCommand();
if (commandElems.size() < 2) {
command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), getArgsError()));
return;
}
ByteArrayWrapper key = command.getKey();
checkDataType(key, RedisDataType.REDIS_LIST, context);
Region keyRegion = getRegion(context, key);
if (keyRegion == null || keyRegion.size() == LIST_EMPTY_SIZE) {
command.setResponse(Coder.getNilResponse(context.getByteBufAllocator()));
return;
}
String indexKey = popType() == ListDirection.LEFT ? "head" : "tail";
String oppositeKey = popType() == ListDirection.RIGHT ? "head" : "tail";
Integer index = 0;
int originalIndex = index;
int incr = popType() == ListDirection.LEFT ? 1 : -1;
ByteArrayWrapper valueWrapper = null;
/**
*
* First attempt to hop over an index by moving the index down one in the meta data region. The
* desired index to remove is held within the field index
*
*/
boolean indexChanged = false;
do {
index = (Integer) keyRegion.get(indexKey);
Integer opp = (Integer) keyRegion.get(oppositeKey);
if (index.equals(opp))
break;
indexChanged = keyRegion.replace(indexKey, index, index + incr);
} while (!indexChanged);
/**
*
* Now attempt to remove the value of the index. We must do a get to ensure a returned value and
* then call remove with the value to ensure no one else has removed it first. Otherwise, try
* other indexes
*
*/
boolean removed = false;
int i = 0;
do {
valueWrapper = (ByteArrayWrapper) keyRegion.get(index);
if (valueWrapper != null)
removed = keyRegion.remove(index, valueWrapper);
if (removed)
break;
/**
*
* If the index has not been removed, we need to look at other indexes. Two cases exist:
*
* ************************** FIRST MISS *********************************** Push occurring at
* the same time, further index update first | This is location of miss | | | | V V [-4] [X]
* [-2] [-1] [0] [1] [2] <-- Direction of index update If this is the first miss, the index is
* re obtained from the meta region and that index is trying. However, if the index in the
* meta data region is not further out, that index is not used and moves on to the second case
* **************************************************************************
*
* ************************* SUBSEQUENT MISSES ****************************** Push occurring
* at the same time, further index update first | This is location of miss | | | | V V [-4]
* [X] [-2] [-1] [0] [1] [2] Direction of index update --> If this is not the first miss then
* we move down to the other end of the list which means the next not empty index will be
* attempted to be removed
* **************************************************************************
*
* If it is the case that the list is empty, it will exit this loop
*
*/
index += incr;
Integer metaIndex = (Integer) keyRegion.get(indexKey);
if (i < 1 && (popType() == ListDirection.LEFT && metaIndex < originalIndex || popType() == ListDirection.RIGHT && metaIndex > originalIndex))
index = metaIndex;
i++;
} while (!removed && keyRegion.size() != LIST_EMPTY_SIZE);
if (valueWrapper != null)
command.setResponse(Coder.getBulkStringResponse(context.getByteBufAllocator(), valueWrapper.toBytes()));
else
command.setResponse(Coder.getNilResponse(context.getByteBufAllocator()));
}
use of org.apache.geode.redis.internal.ByteArrayWrapper in project geode by apache.
the class PushExecutor method executeCommand.
@Override
public void executeCommand(Command command, ExecutionHandlerContext context) {
List<byte[]> commandElems = command.getProcessedCommand();
if (commandElems.size() < 3) {
command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), getArgsError()));
return;
}
ByteArrayWrapper key = command.getKey();
Region<Integer, ByteArrayWrapper> keyRegion = getOrCreateRegion(context, key, RedisDataType.REDIS_LIST);
pushElements(key, commandElems, START_VALUES_INDEX, commandElems.size(), keyRegion, pushType(), context);
int listSize = keyRegion.size() - LIST_EMPTY_SIZE;
command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), listSize));
}
use of org.apache.geode.redis.internal.ByteArrayWrapper in project geode by apache.
the class PushXExecutor method executeCommand.
@Override
public void executeCommand(Command command, ExecutionHandlerContext context) {
List<byte[]> commandElems = command.getProcessedCommand();
if (commandElems.size() < 3) {
command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), getArgsError()));
return;
}
ByteArrayWrapper key = command.getKey();
Region<Integer, ByteArrayWrapper> keyRegion = getRegion(context, key);
if (keyRegion == null) {
command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), NOT_EXISTS));
return;
}
checkDataType(key, RedisDataType.REDIS_LIST, context);
pushElements(key, commandElems, 2, 3, keyRegion, pushType(), context);
int listSize = keyRegion.size() - LIST_EMPTY_SIZE;
command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), listSize));
}
use of org.apache.geode.redis.internal.ByteArrayWrapper in project geode by apache.
the class SCardExecutor method executeCommand.
@SuppressWarnings("unchecked")
@Override
public void executeCommand(Command command, ExecutionHandlerContext context) {
List<byte[]> commandElems = command.getProcessedCommand();
if (commandElems.size() < 2) {
command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.SCARD));
return;
}
ByteArrayWrapper key = command.getKey();
checkDataType(key, RedisDataType.REDIS_SET, context);
Region<ByteArrayWrapper, Boolean> keyRegion = (Region<ByteArrayWrapper, Boolean>) context.getRegionProvider().getRegion(key);
if (keyRegion == null) {
command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), NOT_EXISTS));
return;
}
command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), keyRegion.size()));
}
Aggregations