// Estimate the key length after pos slot for schema. private static int estimatePartLength(int pos, Iterator<PColumn> iterator) { int length = 0; while (iterator.hasNext()) { PColumn column = iterator.next(); if (column.getDataType().isFixedWidth()) { length += SchemaUtil.getFixedByteSize(column); } else { length += 1; // SEPARATOR byte. } } return length; }
// Go through each slot in the schema and try match it with the split byte array. If the split // does not confer to the schema, extends its length to match the schema. private static byte[] processSplit(byte[] split, LinkedHashSet<PColumn> pkColumns) { int pos = 0, offset = 0, maxOffset = split.length; Iterator<PColumn> iterator = pkColumns.iterator(); while (pos < pkColumns.size()) { PColumn column = iterator.next(); if (column.getDataType().isFixedWidth()) { // Fixed width int length = SchemaUtil.getFixedByteSize(column); if (maxOffset - offset < length) { // The split truncates the field. Fill in the rest of the part and any fields that // are missing after this field. int fillInLength = length - (maxOffset - offset); fillInLength += estimatePartLength(pos + 1, iterator); return ByteUtil.fillKey(split, split.length + fillInLength); } // Account for this field, move to next position; offset += length; pos++; } else { // Variable length // If we are the last slot, then we are done. Nothing needs to be filled in. if (pos == pkColumns.size() - 1) { break; } while (offset < maxOffset && split[offset] != QueryConstants.SEPARATOR_BYTE) { offset++; } if (offset == maxOffset) { // The var-length field does not end with a separator and it's not the last field. int fillInLength = 1; // SEPARATOR byte for the current var-length slot. fillInLength += estimatePartLength(pos + 1, iterator); return ByteUtil.fillKey(split, split.length + fillInLength); } // Move to the next position; offset += 1; // skip separator; pos++; } } return split; }