1 /** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package org.apache.hadoop.hbase.coprocessor; 21 22 import java.io.IOException; 23 24 import org.apache.hadoop.hbase.classification.InterfaceAudience; 25 import org.apache.hadoop.hbase.Cell; 26 import org.apache.hadoop.hbase.KeyValue; 27 import org.apache.hadoop.hbase.KeyValueUtil; 28 import org.apache.hadoop.hbase.client.coprocessor.LongColumnInterpreter; 29 30 import com.google.protobuf.Message; 31 32 /** 33 * Defines how value for specific column is interpreted and provides utility 34 * methods like compare, add, multiply etc for them. Takes column family, column 35 * qualifier and return the cell value. Its concrete implementation should 36 * handle null case gracefully. Refer to {@link LongColumnInterpreter} for an 37 * example. 38 * <p> 39 * Takes two generic parameters and three Message parameters. 40 * The cell value type of the interpreter is <T>. 41 * During some computations like sum, average, the return type can be different 42 * than the cell value data type, for eg, sum of int cell values might overflow 43 * in case of a int result, we should use Long for its result. Therefore, this 44 * class mandates to use a different (promoted) data type for result of these 45 * computations <S>. All computations are performed on the promoted data type 46 * <S>. There is a conversion method 47 * {@link ColumnInterpreter#castToReturnType(Object)} which takes a <T> type and 48 * returns a <S> type. 49 * The AggregateImplementation uses PB messages to initialize the 50 * user's ColumnInterpreter implementation, and for sending the responses 51 * back to AggregationClient. 52 * @param <T> Cell value data type 53 * @param <S> Promoted data type 54 * @param <P> PB message that is used to transport initializer specific bytes 55 * @param <Q> PB message that is used to transport Cell (<T>) instance 56 * @param <R> PB message that is used to transport Promoted (<S>) instance 57 */ 58 @InterfaceAudience.Private 59 public abstract class ColumnInterpreter<T, S, P extends Message, 60 Q extends Message, R extends Message> { 61 62 /** 63 * TODO: when removing {@link #getValue(byte[], byte[], KeyValue)}, this method should be made abstract 64 * 65 * @param colFamily 66 * @param colQualifier 67 * @param c 68 * @return value of type T 69 * @throws IOException 70 */ 71 public T getValue(byte[] colFamily, byte[] colQualifier, Cell c) 72 throws IOException { 73 // call the deprecated method for compatiblity. 74 KeyValue kv = KeyValueUtil.ensureKeyValue(c); 75 return getValue(colFamily, colQualifier, kv); 76 } 77 78 /** 79 * This method used to be abstract, and is preserved for compatibility and easy of conversion 80 * from 0.94->0.96. 81 * 82 * Please override {@link #getValue(byte[], byte[], Cell)} instead. 83 */ 84 @Deprecated 85 public T getValue(byte[] colFamily, byte[] colQualifier, KeyValue kv) 86 throws IOException { 87 return null; 88 } 89 90 /** 91 * @param l1 92 * @param l2 93 * @return sum or non null value among (if either of them is null); otherwise 94 * returns a null. 95 */ 96 public abstract S add(S l1, S l2); 97 98 /** 99 * returns the maximum value for this type T 100 * @return max 101 */ 102 103 public abstract T getMaxValue(); 104 105 public abstract T getMinValue(); 106 107 /** 108 * @param o1 109 * @param o2 110 * @return multiplication 111 */ 112 public abstract S multiply(S o1, S o2); 113 114 /** 115 * @param o 116 * @return increment 117 */ 118 public abstract S increment(S o); 119 120 /** 121 * provides casting opportunity between the data types. 122 * @param o 123 * @return cast 124 */ 125 public abstract S castToReturnType(T o); 126 127 /** 128 * This takes care if either of arguments are null. returns 0 if they are 129 * equal or both are null; 130 * <ul> 131 * <li>>0 if l1 > l2 or l1 is not null and l2 is null. 132 * <li>< 0 if l1 < l2 or l1 is null and l2 is not null. 133 */ 134 public abstract int compare(final T l1, final T l2); 135 136 /** 137 * used for computing average of <S> data values. Not providing the divide 138 * method that takes two <S> values as it is not needed as of now. 139 * @param o 140 * @param l 141 * @return Average 142 */ 143 public abstract double divideForAvg(S o, Long l); 144 145 /** 146 * This method should return any additional data that is needed on the 147 * server side to construct the ColumnInterpreter. The server 148 * will pass this to the {@link #initialize} 149 * method. If there is no ColumnInterpreter specific data (for e.g., 150 * {@link LongColumnInterpreter}) then null should be returned. 151 * @return the PB message 152 */ 153 public abstract P getRequestData(); 154 155 /** 156 * This method should initialize any field(s) of the ColumnInterpreter with 157 * a parsing of the passed message bytes (used on the server side). 158 * @param msg 159 */ 160 public abstract void initialize(P msg); 161 162 /** 163 * This method gets the PB message corresponding to the cell type 164 * @param t 165 * @return the PB message for the cell-type instance 166 */ 167 public abstract Q getProtoForCellType(T t); 168 169 /** 170 * This method gets the PB message corresponding to the cell type 171 * @param q 172 * @return the cell-type instance from the PB message 173 */ 174 public abstract T getCellValueFromProto(Q q); 175 176 /** 177 * This method gets the PB message corresponding to the promoted type 178 * @param s 179 * @return the PB message for the promoted-type instance 180 */ 181 public abstract R getProtoForPromotedType(S s); 182 183 /** 184 * This method gets the promoted type from the proto message 185 * @param r 186 * @return the promoted-type instance from the PB message 187 */ 188 public abstract S getPromotedValueFromProto(R r); 189 190 /** 191 * The response message comes as type S. This will convert/cast it to T. 192 * In some sense, performs the opposite of {@link #castToReturnType(Object)} 193 * @param response 194 * @return cast 195 */ 196 public abstract T castToCellType(S response); 197 }