use of org.apache.phoenix.hbase.index.covered.LocalTableState in project phoenix by apache.
the class CoveredColumnIndexCodec method getDeleteForGroup.
/**
* Get all the deletes necessary for a group of columns - logically, the cleanup the index table for a given index.
*
* @param group
* index information
* @return the cleanup for the given index, or <tt>null</tt> if no cleanup is necessary
*/
private IndexUpdate getDeleteForGroup(ColumnGroup group, TableState state, IndexMetaData indexMetaData) {
List<CoveredColumn> refs = group.getColumns();
try {
Pair<Scanner, IndexUpdate> kvs = ((LocalTableState) state).getIndexedColumnsTableState(refs, false, false, indexMetaData);
Pair<Integer, List<ColumnEntry>> columns = getNextEntries(refs, kvs.getFirst(), state.getCurrentRowKey());
// make sure we close the scanner reference
kvs.getFirst().close();
// no change, just return the passed update
if (columns.getFirst() == 0) {
return kvs.getSecond();
}
// have all the column entries, so just turn it into a Delete for the row
// convert the entries to the needed values
byte[] rowKey = composeRowKey(state.getCurrentRowKey(), columns.getFirst(), columns.getSecond());
Delete d = new Delete(rowKey);
d.setTimestamp(state.getCurrentTimestamp());
IndexUpdate update = kvs.getSecond();
update.setUpdate(d);
update.setTable(Bytes.toBytes(group.getTable()));
return update;
} catch (IOException e) {
throw new RuntimeException("Unexpected exception when getting state for columns: " + refs);
}
}
use of org.apache.phoenix.hbase.index.covered.LocalTableState in project phoenix by apache.
the class TestCoveredColumnIndexCodec method testGeneratedIndexUpdates.
/**
* Test that we get back the correct index updates for a given column group
* @throws Exception on failure
*/
@Test
public void testGeneratedIndexUpdates() throws Exception {
ColumnGroup group = new ColumnGroup("test-column-group");
group.add(COLUMN_REF);
final Result emptyState = Result.create(Collections.<Cell>emptyList());
// setup the state we expect for the codec
RegionCoprocessorEnvironment env = Mockito.mock(RegionCoprocessorEnvironment.class);
Configuration conf = new Configuration(false);
Mockito.when(env.getConfiguration()).thenReturn(conf);
LocalHBaseState table = new SimpleTableState(emptyState);
// make a new codec on those kvs
CoveredColumnIndexCodec codec = CoveredColumnIndexCodec.getCodecForTesting(Arrays.asList(group));
// start with a basic put that has some keyvalues
Put p = new Put(PK);
// setup the kvs to add
List<KeyValue> kvs = new ArrayList<KeyValue>();
byte[] v1 = Bytes.toBytes("v1");
KeyValue kv = new KeyValue(PK, FAMILY, QUAL, 1, v1);
kvs.add(kv);
p.add(kv);
byte[] v2 = Bytes.toBytes("v2");
kv = new KeyValue(PK, Bytes.toBytes("family2"), QUAL, 1, v2);
kvs.add(kv);
p.add(kv);
// check the codec for deletes it should send
LocalTableState state = new LocalTableState(env, table, p);
Iterable<IndexUpdate> updates = codec.getIndexDeletes(state, IndexMetaData.NULL_INDEX_META_DATA);
assertFalse("Found index updates without any existing kvs in table!", updates.iterator().next().isValid());
// get the updates with the pending update
state.setCurrentTimestamp(1);
state.addPendingUpdates(kvs);
updates = codec.getIndexUpserts(state, IndexMetaData.NULL_INDEX_META_DATA);
assertTrue("Didn't find index updates for pending primary table update!", updates.iterator().hasNext());
for (IndexUpdate update : updates) {
assertTrue("Update marked as invalid, but should be a pending index write!", update.isValid());
Put m = (Put) update.getUpdate();
// should just be the single update for the column reference
byte[] expected = CoveredColumnIndexCodec.composeRowKey(PK, v1.length, Arrays.asList(toColumnEntry(v1)));
assertArrayEquals("Didn't get expected index value", expected, m.getRow());
}
// then apply a delete
Delete d = new Delete(PK, 2);
// need to set the timestamp here, as would actually happen on the server, unlike what happens
// with puts, where the get the constructor specified timestamp for unspecified methods.
d.deleteFamily(FAMILY, 2);
// setup the next batch of 'current state', basically just ripping out the current state from
// the last round
table = new SimpleTableState(new Result(kvs));
state = new LocalTableState(env, table, d);
state.setCurrentTimestamp(2);
// check the cleanup of the current table, after the puts (mocking a 'next' update)
updates = codec.getIndexDeletes(state, IndexMetaData.NULL_INDEX_META_DATA);
for (IndexUpdate update : updates) {
assertTrue("Didn't have any index cleanup, even though there is current state", update.isValid());
Delete m = (Delete) update.getUpdate();
// should just be the single update for the column reference
byte[] expected = CoveredColumnIndexCodec.composeRowKey(PK, v1.length, Arrays.asList(toColumnEntry(v1)));
assertArrayEquals("Didn't get expected index value", expected, m.getRow());
}
ensureNoUpdatesWhenCoveredByDelete(env, codec, kvs, d);
// now with the delete of the columns
d = new Delete(PK, 2);
d.deleteColumns(FAMILY, QUAL, 2);
ensureNoUpdatesWhenCoveredByDelete(env, codec, kvs, d);
// this delete needs to match timestamps exactly, by contract, to have any effect
d = new Delete(PK, 1);
d.deleteColumn(FAMILY, QUAL, 1);
ensureNoUpdatesWhenCoveredByDelete(env, codec, kvs, d);
}
use of org.apache.phoenix.hbase.index.covered.LocalTableState in project phoenix by apache.
the class TestCoveredColumnIndexCodec method ensureNoUpdatesWhenCoveredByDelete.
private void ensureNoUpdatesWhenCoveredByDelete(RegionCoprocessorEnvironment env, IndexCodec codec, List<KeyValue> currentState, Delete d) throws IOException {
LocalHBaseState table = new SimpleTableState(new Result(currentState));
LocalTableState state = new LocalTableState(env, table, d);
state.setCurrentTimestamp(d.getTimeStamp());
// now we shouldn't see anything when getting the index update
state.addPendingUpdates(d.getFamilyMap().get(FAMILY));
Iterable<IndexUpdate> updates = codec.getIndexUpserts(state, IndexMetaData.NULL_INDEX_META_DATA);
for (IndexUpdate update : updates) {
assertFalse("Had some index updates, though it should have been covered by the delete", update.isValid());
}
}
use of org.apache.phoenix.hbase.index.covered.LocalTableState in project phoenix by apache.
the class CoveredColumnIndexCodec method getIndexUpdateForGroup.
/**
* @param group
* @param state
* @return the update that should be made to the table
*/
private IndexUpdate getIndexUpdateForGroup(ColumnGroup group, TableState state, IndexMetaData indexMetaData) {
List<CoveredColumn> refs = group.getColumns();
try {
Pair<Scanner, IndexUpdate> stateInfo = ((LocalTableState) state).getIndexedColumnsTableState(refs, false, false, indexMetaData);
Scanner kvs = stateInfo.getFirst();
Pair<Integer, List<ColumnEntry>> columns = getNextEntries(refs, kvs, state.getCurrentRowKey());
// make sure we close the scanner
kvs.close();
if (columns.getFirst().intValue() == 0) {
return stateInfo.getSecond();
}
// have all the column entries, so just turn it into a Delete for the row
// convert the entries to the needed values
byte[] rowKey = composeRowKey(state.getCurrentRowKey(), columns.getFirst(), columns.getSecond());
Put p = new Put(rowKey, state.getCurrentTimestamp());
// add the columns to the put
addColumnsToPut(p, columns.getSecond());
// update the index info
IndexUpdate update = stateInfo.getSecond();
update.setTable(Bytes.toBytes(group.getTable()));
update.setUpdate(p);
return update;
} catch (IOException e) {
throw new RuntimeException("Unexpected exception when getting state for columns: " + refs);
}
}
use of org.apache.phoenix.hbase.index.covered.LocalTableState in project phoenix by apache.
the class CoveredColumnIndexer method getIndexUpdateForFilteredRows.
@Override
public Collection<Pair<Mutation, byte[]>> getIndexUpdateForFilteredRows(Collection<KeyValue> filtered, IndexMetaData indexMetaData) throws IOException {
// stores all the return values
IndexUpdateManager updateMap = new IndexUpdateManager(indexMetaData);
// batch the updates by row to make life easier and ordered
Collection<Batch> batches = batchByRow(filtered);
for (Batch batch : batches) {
Cell curKV = batch.getKvs().iterator().next();
Put p = new Put(curKV.getRowArray(), curKV.getRowOffset(), curKV.getRowLength());
for (Cell kv : batch.getKvs()) {
// we only need to cleanup Put entries
byte type = kv.getTypeByte();
Type t = KeyValue.Type.codeToType(type);
if (!t.equals(Type.Put)) {
continue;
}
// add the kv independently
p.add(kv);
}
// do the usual thing as for deletes
Collection<Batch> timeBatch = createTimestampBatchesFromMutation(p);
LocalTableState state = new LocalTableState(env, localTable, p);
for (Batch entry : timeBatch) {
//just set the timestamp on the table - it already has all the future state
state.setCurrentTimestamp(entry.getTimestamp());
this.addDeleteUpdatesToMap(updateMap, state, entry.getTimestamp(), indexMetaData);
}
}
return updateMap.toMap();
}
Aggregations