1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 package org.apache.hadoop.hbase.regionserver;
19
20 import org.apache.hadoop.hbase.classification.InterfaceAudience;
21 import org.apache.hadoop.hbase.client.Mutation;
22 import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
23
24 /**
25 * Wraps together the mutations which are applied as a batch to the region and their operation
26 * status and WALEdits.
27 * @see org.apache.hadoop.hbase.coprocessor.
28 * RegionObserver#preBatchMutate(ObserverContext, MiniBatchOperationInProgress)
29 * @see org.apache.hadoop.hbase.coprocessor.
30 * RegionObserver#postBatchMutate(ObserverContext, MiniBatchOperationInProgress)
31 * @param <T> Pair<Mutation, Integer> pair of Mutations and associated rowlock ids .
32 */
33 @InterfaceAudience.LimitedPrivate("Coprocessors")
34 public class MiniBatchOperationInProgress<T> {
35 private final T[] operations;
36 private Mutation[][] operationsFromCoprocessors;
37 private final OperationStatus[] retCodeDetails;
38 private final WALEdit[] walEditsFromCoprocessors;
39 private final int firstIndex;
40 private final int lastIndexExclusive;
41
42 public MiniBatchOperationInProgress(T[] operations, OperationStatus[] retCodeDetails,
43 WALEdit[] walEditsFromCoprocessors, int firstIndex, int lastIndexExclusive) {
44 this.operations = operations;
45 this.retCodeDetails = retCodeDetails;
46 this.walEditsFromCoprocessors = walEditsFromCoprocessors;
47 this.firstIndex = firstIndex;
48 this.lastIndexExclusive = lastIndexExclusive;
49 }
50
51 /**
52 * @return The number of operations(Mutations) involved in this batch.
53 */
54 public int size() {
55 return this.lastIndexExclusive - this.firstIndex;
56 }
57
58 /**
59 * @param index
60 * @return The operation(Mutation) at the specified position.
61 */
62 public T getOperation(int index) {
63 return operations[getAbsoluteIndex(index)];
64 }
65
66 /**
67 * Sets the status code for the operation(Mutation) at the specified position.
68 * By setting this status, {@link org.apache.hadoop.hbase.coprocessor.RegionObserver}
69 * can make HRegion to skip Mutations.
70 * @param index
71 * @param opStatus
72 */
73 public void setOperationStatus(int index, OperationStatus opStatus) {
74 this.retCodeDetails[getAbsoluteIndex(index)] = opStatus;
75 }
76
77 /**
78 * @param index
79 * @return Gets the status code for the operation(Mutation) at the specified position.
80 */
81 public OperationStatus getOperationStatus(int index) {
82 return this.retCodeDetails[getAbsoluteIndex(index)];
83 }
84
85 /**
86 * Sets the walEdit for the operation(Mutation) at the specified position.
87 * @param index
88 * @param walEdit
89 */
90 public void setWalEdit(int index, WALEdit walEdit) {
91 this.walEditsFromCoprocessors[getAbsoluteIndex(index)] = walEdit;
92 }
93
94 /**
95 * @param index
96 * @return Gets the walEdit for the operation(Mutation) at the specified position.
97 */
98 public WALEdit getWalEdit(int index) {
99 return this.walEditsFromCoprocessors[getAbsoluteIndex(index)];
100 }
101
102 private int getAbsoluteIndex(int index) {
103 if (index < 0 || this.firstIndex + index >= this.lastIndexExclusive) {
104 throw new ArrayIndexOutOfBoundsException(index);
105 }
106 return this.firstIndex + index;
107 }
108
109 /**
110 * Add more Mutations corresponding to the Mutation at the given index to be committed atomically
111 * in the same batch. These mutations are applied to the WAL and applied to the memstore as well.
112 * The timestamp of the cells in the given Mutations MUST be obtained from the original mutation.
113 *
114 * @param index the index that corresponds to the original mutation index in the batch
115 * @param newOperations the Mutations to add
116 */
117 public void addOperationsFromCP(int index, Mutation[] newOperations) {
118 if (this.operationsFromCoprocessors == null) {
119 // lazy allocation to save on object allocation in case this is not used
120 this.operationsFromCoprocessors = new Mutation[operations.length][];
121 }
122 this.operationsFromCoprocessors[getAbsoluteIndex(index)] = newOperations;
123 }
124
125 public Mutation[] getOperationsFromCoprocessors(int index) {
126 return operationsFromCoprocessors == null ? null :
127 operationsFromCoprocessors[getAbsoluteIndex(index)];
128 }
129 }