001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.regionserver; 019 020import org.apache.hadoop.hbase.HBaseInterfaceAudience; 021import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; 022import org.apache.yetus.audience.InterfaceAudience; 023import org.apache.hadoop.hbase.client.Mutation; 024import org.apache.hadoop.hbase.wal.WALEdit; 025 026/** 027 * Wraps together the mutations which are applied as a batch to the region and their operation 028 * status and WALEdits. 029 * @see org.apache.hadoop.hbase.coprocessor.RegionObserver#preBatchMutate( 030 * org.apache.hadoop.hbase.coprocessor.ObserverContext, MiniBatchOperationInProgress) 031 * @see org.apache.hadoop.hbase.coprocessor.RegionObserver#postBatchMutate( 032 * org.apache.hadoop.hbase.coprocessor.ObserverContext, MiniBatchOperationInProgress) 033 * @param T Pair<Mutation, Integer> pair of Mutations and associated rowlock ids . 034 */ 035@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC) 036public class MiniBatchOperationInProgress<T> { 037 private final T[] operations; 038 private Mutation[][] operationsFromCoprocessors; 039 private final OperationStatus[] retCodeDetails; 040 private final WALEdit[] walEditsFromCoprocessors; 041 private final int firstIndex; 042 private final int lastIndexExclusive; 043 044 private int readyToWriteCount = 0; 045 private int cellCount = 0; 046 private int numOfPuts = 0; 047 private int numOfDeletes = 0; 048 private int numOfIncrements = 0; 049 private int numOfAppends = 0; 050 051 052 public MiniBatchOperationInProgress(T[] operations, OperationStatus[] retCodeDetails, 053 WALEdit[] walEditsFromCoprocessors, int firstIndex, int lastIndexExclusive, 054 int readyToWriteCount) { 055 Preconditions.checkArgument(readyToWriteCount <= (lastIndexExclusive - firstIndex)); 056 this.operations = operations; 057 this.retCodeDetails = retCodeDetails; 058 this.walEditsFromCoprocessors = walEditsFromCoprocessors; 059 this.firstIndex = firstIndex; 060 this.lastIndexExclusive = lastIndexExclusive; 061 this.readyToWriteCount = readyToWriteCount; 062 } 063 064 /** 065 * @return The number of operations(Mutations) involved in this batch. 066 */ 067 public int size() { 068 return this.lastIndexExclusive - this.firstIndex; 069 } 070 071 /** 072 * @param index 073 * @return The operation(Mutation) at the specified position. 074 */ 075 public T getOperation(int index) { 076 return operations[getAbsoluteIndex(index)]; 077 } 078 079 /** 080 * Sets the status code for the operation(Mutation) at the specified position. 081 * By setting this status, {@link org.apache.hadoop.hbase.coprocessor.RegionObserver} 082 * can make HRegion to skip Mutations. 083 * @param index 084 * @param opStatus 085 */ 086 public void setOperationStatus(int index, OperationStatus opStatus) { 087 this.retCodeDetails[getAbsoluteIndex(index)] = opStatus; 088 } 089 090 /** 091 * @param index 092 * @return Gets the status code for the operation(Mutation) at the specified position. 093 */ 094 public OperationStatus getOperationStatus(int index) { 095 return this.retCodeDetails[getAbsoluteIndex(index)]; 096 } 097 098 /** 099 * Sets the walEdit for the operation(Mutation) at the specified position. 100 * @param index 101 * @param walEdit 102 */ 103 public void setWalEdit(int index, WALEdit walEdit) { 104 this.walEditsFromCoprocessors[getAbsoluteIndex(index)] = walEdit; 105 } 106 107 /** 108 * @param index 109 * @return Gets the walEdit for the operation(Mutation) at the specified position. 110 */ 111 public WALEdit getWalEdit(int index) { 112 return this.walEditsFromCoprocessors[getAbsoluteIndex(index)]; 113 } 114 115 private int getAbsoluteIndex(int index) { 116 if (index < 0 || this.firstIndex + index >= this.lastIndexExclusive) { 117 throw new ArrayIndexOutOfBoundsException(index); 118 } 119 return this.firstIndex + index; 120 } 121 122 /** 123 * Add more Mutations corresponding to the Mutation at the given index to be committed atomically 124 * in the same batch. These mutations are applied to the WAL and applied to the memstore as well. 125 * The timestamp of the cells in the given Mutations MUST be obtained from the original mutation. 126 * <b>Note:</b> The durability from CP will be replaced by the durability of corresponding mutation. 127 * <b>Note:</b> Currently only supports Put and Delete operations. 128 * @param index the index that corresponds to the original mutation index in the batch 129 * @param newOperations the Mutations to add 130 */ 131 public void addOperationsFromCP(int index, Mutation[] newOperations) { 132 if (this.operationsFromCoprocessors == null) { 133 // lazy allocation to save on object allocation in case this is not used 134 this.operationsFromCoprocessors = new Mutation[operations.length][]; 135 } 136 this.operationsFromCoprocessors[getAbsoluteIndex(index)] = newOperations; 137 } 138 139 public Mutation[] getOperationsFromCoprocessors(int index) { 140 return operationsFromCoprocessors == null ? null : 141 operationsFromCoprocessors[getAbsoluteIndex(index)]; 142 } 143 144 public int getReadyToWriteCount() { 145 return readyToWriteCount; 146 } 147 148 public int getLastIndexExclusive() { 149 return lastIndexExclusive; 150 } 151 152 public int getCellCount() { 153 return cellCount; 154 } 155 156 public void addCellCount(int cellCount) { 157 this.cellCount += cellCount; 158 } 159 160 public int getNumOfPuts() { 161 return numOfPuts; 162 } 163 164 public void incrementNumOfPuts() { 165 this.numOfPuts += 1; 166 } 167 168 public int getNumOfDeletes() { 169 return numOfDeletes; 170 } 171 172 public void incrementNumOfDeletes() { 173 this.numOfDeletes += 1; 174 } 175 176 public int getNumOfIncrements() { 177 return numOfIncrements; 178 } 179 180 public void incrementNumOfIncrements() { 181 this.numOfIncrements += 1; 182 } 183 184 public int getNumOfAppends() { 185 return numOfAppends; 186 } 187 188 public void incrementNumOfAppends() { 189 this.numOfAppends += 1; 190 } 191}