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.hadoop.hbase.client.Mutation; 022import org.apache.hadoop.hbase.wal.WALEdit; 023import org.apache.yetus.audience.InterfaceAudience; 024 025import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; 026 027/** 028 * Wraps together the mutations which are applied as a batch to the region and their operation 029 * status and WALEdits. 030 * @see org.apache.hadoop.hbase.coprocessor.RegionObserver#preBatchMutate( 031 * org.apache.hadoop.hbase.coprocessor.ObserverContext, MiniBatchOperationInProgress) 032 * @see org.apache.hadoop.hbase.coprocessor.RegionObserver#postBatchMutate( 033 * org.apache.hadoop.hbase.coprocessor.ObserverContext, MiniBatchOperationInProgress) 034 * @param T Pair<Mutation, Integer> pair of Mutations and associated rowlock ids . 035 */ 036@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC) 037public class MiniBatchOperationInProgress<T> { 038 private final T[] operations; 039 private Mutation[][] operationsFromCoprocessors; 040 private final OperationStatus[] retCodeDetails; 041 private final WALEdit[] walEditsFromCoprocessors; 042 private final int firstIndex; 043 private final int lastIndexExclusive; 044 045 private int readyToWriteCount = 0; 046 private int cellCount = 0; 047 private int numOfPuts = 0; 048 private int numOfDeletes = 0; 049 private int numOfIncrements = 0; 050 private int numOfAppends = 0; 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 /** Returns The number of operations(Mutations) involved in this batch. */ 065 public int size() { 066 return this.lastIndexExclusive - this.firstIndex; 067 } 068 069 /** 070 * n * @return The operation(Mutation) at the specified position. 071 */ 072 public T getOperation(int index) { 073 return operations[getAbsoluteIndex(index)]; 074 } 075 076 /** 077 * Sets the status code for the operation(Mutation) at the specified position. By setting this 078 * status, {@link org.apache.hadoop.hbase.coprocessor.RegionObserver} can make HRegion to skip 079 * Mutations. nn 080 */ 081 public void setOperationStatus(int index, OperationStatus opStatus) { 082 this.retCodeDetails[getAbsoluteIndex(index)] = opStatus; 083 } 084 085 /** 086 * n * @return Gets the status code for the operation(Mutation) at the specified position. 087 */ 088 public OperationStatus getOperationStatus(int index) { 089 return this.retCodeDetails[getAbsoluteIndex(index)]; 090 } 091 092 /** 093 * Sets the walEdit for the operation(Mutation) at the specified position. nn 094 */ 095 public void setWalEdit(int index, WALEdit walEdit) { 096 this.walEditsFromCoprocessors[getAbsoluteIndex(index)] = walEdit; 097 } 098 099 /** 100 * n * @return Gets the walEdit for the operation(Mutation) at the specified position. 101 */ 102 public WALEdit getWalEdit(int index) { 103 return this.walEditsFromCoprocessors[getAbsoluteIndex(index)]; 104 } 105 106 private int getAbsoluteIndex(int index) { 107 if (index < 0 || this.firstIndex + index >= this.lastIndexExclusive) { 108 throw new ArrayIndexOutOfBoundsException(index); 109 } 110 return this.firstIndex + index; 111 } 112 113 /** 114 * Add more Mutations corresponding to the Mutation at the given index to be committed atomically 115 * in the same batch. These mutations are applied to the WAL and applied to the memstore as well. 116 * The timestamp of the cells in the given Mutations MUST be obtained from the original mutation. 117 * <b>Note:</b> The durability from CP will be replaced by the durability of corresponding 118 * mutation. <b>Note:</b> Currently only supports Put and Delete operations. 119 * @param index the index that corresponds to the original mutation index in the batch 120 * @param newOperations the Mutations to add 121 */ 122 public void addOperationsFromCP(int index, Mutation[] newOperations) { 123 if (this.operationsFromCoprocessors == null) { 124 // lazy allocation to save on object allocation in case this is not used 125 this.operationsFromCoprocessors = new Mutation[operations.length][]; 126 } 127 this.operationsFromCoprocessors[getAbsoluteIndex(index)] = newOperations; 128 } 129 130 public Mutation[] getOperationsFromCoprocessors(int index) { 131 return operationsFromCoprocessors == null 132 ? null 133 : operationsFromCoprocessors[getAbsoluteIndex(index)]; 134 } 135 136 public int getReadyToWriteCount() { 137 return readyToWriteCount; 138 } 139 140 public int getLastIndexExclusive() { 141 return lastIndexExclusive; 142 } 143 144 public int getCellCount() { 145 return cellCount; 146 } 147 148 public void addCellCount(int cellCount) { 149 this.cellCount += cellCount; 150 } 151 152 public int getNumOfPuts() { 153 return numOfPuts; 154 } 155 156 public void incrementNumOfPuts() { 157 this.numOfPuts += 1; 158 } 159 160 public int getNumOfDeletes() { 161 return numOfDeletes; 162 } 163 164 public void incrementNumOfDeletes() { 165 this.numOfDeletes += 1; 166 } 167 168 public int getNumOfIncrements() { 169 return numOfIncrements; 170 } 171 172 public void incrementNumOfIncrements() { 173 this.numOfIncrements += 1; 174 } 175 176 public int getNumOfAppends() { 177 return numOfAppends; 178 } 179 180 public void incrementNumOfAppends() { 181 this.numOfAppends += 1; 182 } 183}