Github user JamesRTaylor commented on a diff in the pull request: https://github.com/apache/phoenix/pull/129#discussion_r45307359 --- Diff: phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java --- @@ -410,149 +642,293 @@ private static long calculateMutationSize(List<Mutation> mutations) { return byteSize; } + private boolean hasKeyValueColumn(PTable table, PTable index) { + IndexMaintainer maintainer = index.getIndexMaintainer(table, connection); + return !maintainer.getAllColumns().isEmpty(); + } + + private void divideImmutableIndexes(Iterator<PTable> enabledImmutableIndexes, PTable table, List<PTable> rowKeyIndexes, List<PTable> keyValueIndexes) { + while (enabledImmutableIndexes.hasNext()) { + PTable index = enabledImmutableIndexes.next(); + if (index.getIndexType() != IndexType.LOCAL) { + if (hasKeyValueColumn(table, index)) { + keyValueIndexes.add(index); + } else { + rowKeyIndexes.add(index); + } + } + } + } + private class MetaDataAwareHTable extends DelegateHTableInterface { + private final TableRef tableRef; + + private MetaDataAwareHTable(HTableInterface delegate, TableRef tableRef) { + super(delegate); + this.tableRef = tableRef; + } + + /** + * Called by Tephra when a transaction is aborted. We have this wrapper so that we get an + * opportunity to attach our index meta data to the mutations such that we can also undo + * the index mutations. + */ + @Override + public void delete(List<Delete> deletes) throws IOException { + try { + PTable table = tableRef.getTable(); + List<PTable> indexes = table.getIndexes(); + Iterator<PTable> enabledIndexes = IndexMaintainer.nonDisabledIndexIterator(indexes.iterator()); + if (enabledIndexes.hasNext()) { + List<PTable> keyValueIndexes = Collections.emptyList(); + ImmutableBytesWritable indexMetaDataPtr = new ImmutableBytesWritable(); + boolean attachMetaData = table.getIndexMaintainers(indexMetaDataPtr, connection); + if (table.isImmutableRows()) { + List<PTable> rowKeyIndexes = Lists.newArrayListWithExpectedSize(indexes.size()); + keyValueIndexes = Lists.newArrayListWithExpectedSize(indexes.size()); + divideImmutableIndexes(enabledIndexes, table, rowKeyIndexes, keyValueIndexes); + // Generate index deletes for immutable indexes that only reference row key + // columns and submit directly here. + ImmutableBytesWritable ptr = new ImmutableBytesWritable(); + for (PTable index : rowKeyIndexes) { + List<Delete> indexDeletes = IndexUtil.generateDeleteIndexData(table, index, deletes, ptr, connection.getKeyValueBuilder(), connection); + HTableInterface hindex = connection.getQueryServices().getTable(index.getPhysicalName().getBytes()); + hindex.delete(indexDeletes); + } + } + + // If we have mutable indexes, local immutable indexes, or global immutable indexes + // that reference key value columns, setup index meta data and attach here. In this + // case updates to the indexes will be generated on the server side. + // An alternative would be to let Tephra track the row keys for the immutable index + // by adding it as a transaction participant (soon we can prevent any conflict + // detection from occurring) with the downside being the additional memory required. + if (!keyValueIndexes.isEmpty()) { + attachMetaData = true; + IndexMaintainer.serializeAdditional(table, indexMetaDataPtr, keyValueIndexes, connection); + } + if (attachMetaData) { + setMetaDataOnMutations(tableRef, deletes, indexMetaDataPtr); + } + } + delegate.delete(deletes); + } catch (SQLException e) { + throw new IOException(e); + } + } + } + @SuppressWarnings("deprecation") - public void commit() throws SQLException { + private void send(Iterator<TableRef> tableRefIterator) throws SQLException { int i = 0; - PName tenantId = connection.getTenantId(); - long[] serverTimeStamps = validate(); - Iterator<Map.Entry<TableRef, Map<ImmutableBytesPtr,RowMutationState>>> iterator = this.mutations.entrySet().iterator(); + long[] serverTimeStamps = null; + boolean sendAll = false; + // Validate up front if not transactional so that we --- End diff -- Remove this comment
--- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---