public static List<Mutation> generateIndexData(final PTable table, PTable index,
List<Mutation> dataMutations, ImmutableBytesWritable ptr, KeyValueBuilder builder)
throws SQLException {
try {
IndexMaintainer maintainer = index.getIndexMaintainer(table);
maintainer.setKvBuilder(builder);
List<Mutation> indexMutations = Lists.newArrayListWithExpectedSize(dataMutations.size());
for (final Mutation dataMutation : dataMutations) {
long ts = MetaDataUtil.getClientTimeStamp(dataMutation);
ptr.set(dataMutation.getRow());
if (dataMutation instanceof Put) {
// TODO: is this more efficient than looking in our mutation map
// using the key plus finding the PColumn?
ValueGetter valueGetter = new ValueGetter() {
@Override
public ImmutableBytesPtr getLatestValue(ColumnReference ref) {
// Always return null for our empty key value, as this will cause the index
// maintainer to always treat this Put as a new row.
if (isEmptyKeyValue(table, ref)) {
return null;
}
Map<byte [], List<KeyValue>> familyMap = dataMutation.getFamilyMap();
byte[] family = ref.getFamily();
List<KeyValue> kvs = familyMap.get(family);
if (kvs == null) {
return null;
}
byte[] qualifier = ref.getQualifier();
for (KeyValue kv : kvs) {
if (Bytes.compareTo(kv.getBuffer(), kv.getFamilyOffset(), kv.getFamilyLength(), family, 0, family.length) == 0 &&
Bytes.compareTo(kv.getBuffer(), kv.getQualifierOffset(), kv.getQualifierLength(), qualifier, 0, qualifier.length) == 0) {
return new ImmutableBytesPtr(kv.getBuffer(), kv.getValueOffset(), kv.getValueLength());
}
}
return null;
}
};
indexMutations.add(maintainer.buildUpdateMutation(valueGetter, ptr, ts));
} else {
if (!maintainer.getIndexedColumns().isEmpty()) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.NO_DELETE_IF_IMMUTABLE_INDEX).setSchemaName(table.getSchemaName().getString())
.setTableName(table.getTableName().getString()).build().buildException();
}
indexMutations.add(maintainer.buildDeleteMutation(ptr, ts));
}
}
return indexMutations;
} catch (IOException e) {
throw new SQLException(e);