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 049 050 public MiniBatchOperationInProgress(T[] operations, OperationStatus[] retCodeDetails, 051 WALEdit[] walEditsFromCoprocessors, int firstIndex, int lastIndexExclusive, 052 int readyToWriteCount) { 053 Preconditions.checkArgument(readyToWriteCount <= (lastIndexExclusive - firstIndex)); 054 this.operations = operations; 055 this.retCodeDetails = retCodeDetails; 056 this.walEditsFromCoprocessors = walEditsFromCoprocessors; 057 this.firstIndex = firstIndex; 058 this.lastIndexExclusive = lastIndexExclusive; 059 this.readyToWriteCount = readyToWriteCount; 060 } 061 062 /** 063 * @return The number of operations(Mutations) involved in this batch. 064 */ 065 public int size() { 066 return this.lastIndexExclusive - this.firstIndex; 067 } 068 069 /** 070 * @param index 071 * @return The operation(Mutation) at the specified position. 072 */ 073 public T getOperation(int index) { 074 return operations[getAbsoluteIndex(index)]; 075 } 076 077 /** 078 * Sets the status code for the operation(Mutation) at the specified position. 079 * By setting this status, {@link org.apache.hadoop.hbase.coprocessor.RegionObserver} 080 * can make HRegion to skip Mutations. 081 * @param index 082 * @param opStatus 083 */ 084 public void setOperationStatus(int index, OperationStatus opStatus) { 085 this.retCodeDetails[getAbsoluteIndex(index)] = opStatus; 086 } 087 088 /** 089 * @param index 090 * @return Gets the status code for the operation(Mutation) at the specified position. 091 */ 092 public OperationStatus getOperationStatus(int index) { 093 return this.retCodeDetails[getAbsoluteIndex(index)]; 094 } 095 096 /** 097 * Sets the walEdit for the operation(Mutation) at the specified position. 098 * @param index 099 * @param walEdit 100 */ 101 public void setWalEdit(int index, WALEdit walEdit) { 102 this.walEditsFromCoprocessors[getAbsoluteIndex(index)] = walEdit; 103 } 104 105 /** 106 * @param index 107 * @return Gets the walEdit for the operation(Mutation) at the specified position. 108 */ 109 public WALEdit getWalEdit(int index) { 110 return this.walEditsFromCoprocessors[getAbsoluteIndex(index)]; 111 } 112 113 private int getAbsoluteIndex(int index) { 114 if (index < 0 || this.firstIndex + index >= this.lastIndexExclusive) { 115 throw new ArrayIndexOutOfBoundsException(index); 116 } 117 return this.firstIndex + index; 118 } 119 120 /** 121 * Add more Mutations corresponding to the Mutation at the given index to be committed atomically 122 * in the same batch. These mutations are applied to the WAL and applied to the memstore as well. 123 * The timestamp of the cells in the given Mutations MUST be obtained from the original mutation. 124 * <b>Note:</b> The durability from CP will be replaced by the durability of corresponding mutation. 125 * @param index the index that corresponds to the original mutation index in the batch 126 * @param newOperations the Mutations to add 127 */ 128 public void addOperationsFromCP(int index, Mutation[] newOperations) { 129 if (this.operationsFromCoprocessors == null) { 130 // lazy allocation to save on object allocation in case this is not used 131 this.operationsFromCoprocessors = new Mutation[operations.length][]; 132 } 133 this.operationsFromCoprocessors[getAbsoluteIndex(index)] = newOperations; 134 } 135 136 public Mutation[] getOperationsFromCoprocessors(int index) { 137 return operationsFromCoprocessors == null ? null : 138 operationsFromCoprocessors[getAbsoluteIndex(index)]; 139 } 140 141 public int getReadyToWriteCount() { 142 return readyToWriteCount; 143 } 144 145 public int getLastIndexExclusive() { 146 return lastIndexExclusive; 147 } 148 149 public int getCellCount() { 150 return cellCount; 151 } 152 153 public void addCellCount(int cellCount) { 154 this.cellCount += cellCount; 155 } 156 157 public int getNumOfPuts() { 158 return numOfPuts; 159 } 160 161 public void incrementNumOfPuts() { 162 this.numOfPuts += 1; 163 } 164 165 public int getNumOfDeletes() { 166 return numOfDeletes; 167 } 168 169 public void incrementNumOfDeletes() { 170 this.numOfDeletes += 1; 171 } 172}