int totalValueLen = 0;
for (FilterColumnValueDetail fcvd : colDetails) {
totalValueLen += fcvd.maxValueLength;
}
int userTabRowKeyLen = userTabRowKey == null ? 0 : userTabRowKey.length;
ByteArrayBuilder builder =
ByteArrayBuilder.allocate(commonKey.length + totalValueLen + userTabRowKeyLen);
builder.put(commonKey);
for (int i = 0; i < colDetails.size(); i++) {
FilterColumnValueDetail fcvd = colDetails.get(i);
if (i == colDetails.size() - 1) {
// This is the last column in the colDetails. Here the range check can come
if (isStartKey) {
if (fcvd.compareOp == null) {
// This can happen when the condition is a range condition and only upper bound is
// specified. ie. c1<100
// Now the column value can be specified as 0 bytes. Just we need to advance the byte[]
assert fcvd instanceof FilterColumnValueRange;
assert fcvd.value == null;
builder.position(builder.position() + fcvd.maxValueLength);
} else if (fcvd.compareOp.equals(CompareOp.EQUAL)
|| fcvd.compareOp.equals(CompareOp.GREATER_OR_EQUAL)) {
copyColumnValueToKey(builder, fcvd.value, fcvd.maxValueLength, fcvd.valueType);
} else if (fcvd.compareOp.equals(CompareOp.GREATER)) {
// We can go with the value + 1
// For eg : if type is int and value is 45, make startkey considering value as 46
// If type is String and value is 'ad' make startkey considering value as 'ae'
copyColumnValueToKey(builder, fcvd.value, fcvd.maxValueLength, fcvd.valueType);
IndexUtils.incrementValue(builder.array(), false);
}
} else {
CompareOp op = fcvd.compareOp;
byte[] value = fcvd.value;
if (fcvd instanceof FilterColumnValueRange) {
op = ((FilterColumnValueRange) fcvd).getUpperBoundCompareOp();
value = ((FilterColumnValueRange) fcvd).getUpperBoundValue();
}
if (op == null) {
// This can happen when the condition is a range condition and only lower bound is
// specified. ie. c1>=10
assert fcvd instanceof FilterColumnValueRange;
assert value == null;
// Here the stop row is already partially built. As there is no upper bound all the
// possibles values for that column we need to consider. Well the max value for a
// column with maxValueLength=10 will a byte array of 10 bytes with all bytes as FF.
// But we can put this FF bytes into the stop row because the stop row will not be
// considered by the scanner. So we need to increment this by 1.
// We can increment the byte[] created until now by 1.
byte[] stopRowTillNow = builder.array(0, builder.position());
stopRowTillNow = IndexUtils.incrementValue(stopRowTillNow, true);
// Now we need to copy back this incremented value to the builder.
builder.position(0);
builder.put(stopRowTillNow);
// Now just advance the builder pos by fcvd.maxValueLength as we need all 0 bytes
builder.position(builder.position() + fcvd.maxValueLength);
} else if (op.equals(CompareOp.EQUAL) || op.equals(CompareOp.LESS_OR_EQUAL)) {
copyColumnValueToKey(builder, value, fcvd.maxValueLength, fcvd.valueType);
IndexUtils.incrementValue(builder.array(), false);
} else if (op.equals(CompareOp.LESS)) {
copyColumnValueToKey(builder, value, fcvd.maxValueLength, fcvd.valueType);
}
}
} else {
// For all other columns other than the last column the condition must be EQUALS
copyColumnValueToKey(builder, fcvd.value, fcvd.maxValueLength, fcvd.valueType);
}
}
if (userTabRowKeyLen > 0) {
builder.put(userTabRowKey);
}
return builder.array();
}