001/* 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.client.coprocessor; 020 021import java.io.IOException; 022import java.math.BigDecimal; 023import java.math.RoundingMode; 024 025import org.apache.hadoop.hbase.Cell; 026import org.apache.hadoop.hbase.CellUtil; 027import org.apache.hadoop.hbase.HBaseInterfaceAudience; 028import org.apache.hadoop.hbase.PrivateCellUtil; 029import org.apache.yetus.audience.InterfaceAudience; 030import org.apache.yetus.audience.InterfaceStability; 031import org.apache.hadoop.hbase.coprocessor.ColumnInterpreter; 032import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.BigDecimalMsg; 033import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.EmptyMsg; 034import org.apache.hadoop.hbase.util.ByteStringer; 035import org.apache.hadoop.hbase.util.Bytes; 036 037/** 038 * ColumnInterpreter for doing Aggregation's with BigDecimal columns. This class 039 * is required at the RegionServer also. 040 * 041 */ 042@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC) 043@InterfaceStability.Evolving 044public class BigDecimalColumnInterpreter extends ColumnInterpreter<BigDecimal, BigDecimal, 045 EmptyMsg, BigDecimalMsg, BigDecimalMsg> { 046 047 @Override 048 public BigDecimal getValue(byte[] colFamily, byte[] colQualifier, Cell kv) 049 throws IOException { 050 if (kv == null || CellUtil.cloneValue(kv) == null) { 051 return null; 052 } 053 return PrivateCellUtil.getValueAsBigDecimal(kv).setScale(2, RoundingMode.HALF_EVEN); 054 } 055 056 @Override 057 public BigDecimal add(BigDecimal bd1, BigDecimal bd2) { 058 if (bd1 == null ^ bd2 == null) { 059 return (bd1 == null) ? bd2 : bd1; // either of one is null. 060 } 061 if (bd1 == null) { 062 return null; 063 } 064 return bd1.add(bd2); 065 } 066 067 @Override 068 public int compare(final BigDecimal bd1, final BigDecimal bd2) { 069 if (bd1 == null ^ bd2 == null) { 070 return bd1 == null ? -1 : 1; // either of one is null. 071 } 072 if (bd1 == null) { 073 return 0; // both are null 074 } 075 return bd1.compareTo(bd2); // natural ordering. 076 } 077 078 @Override 079 public BigDecimal getMaxValue() { 080 return BigDecimal.valueOf(Double.MAX_VALUE); 081 } 082 083 @Override 084 public BigDecimal increment(BigDecimal bd) { 085 return bd == null ? null : (bd.add(BigDecimal.ONE)); 086 } 087 088 @Override 089 public BigDecimal multiply(BigDecimal bd1, BigDecimal bd2) { 090 return (bd1 == null || bd2 == null) ? null : bd1.multiply(bd2) 091 .setScale(2,RoundingMode.HALF_EVEN); 092 } 093 094 @Override 095 public BigDecimal getMinValue() { 096 return BigDecimal.valueOf(Double.MIN_VALUE); 097 } 098 099 @Override 100 public double divideForAvg(BigDecimal bd1, Long l2) { 101 return (l2 == null || bd1 == null) ? Double.NaN : (bd1.doubleValue() / l2 102 .doubleValue()); 103 } 104 105 @Override 106 public BigDecimal castToReturnType(BigDecimal bd) { 107 return bd; 108 } 109 110 @Override 111 public BigDecimal castToCellType(BigDecimal bd) { 112 return bd; 113 } 114 115 @Override 116 public EmptyMsg getRequestData() { 117 return EmptyMsg.getDefaultInstance(); 118 } 119 120 @Override 121 public void initialize(EmptyMsg msg) { 122 //nothing 123 } 124 125 private BigDecimalMsg getProtoForType(BigDecimal t) { 126 BigDecimalMsg.Builder builder = BigDecimalMsg.newBuilder(); 127 return builder.setBigdecimalMsg(ByteStringer.wrap(Bytes.toBytes(t))).build(); 128 } 129 130 @Override 131 public BigDecimalMsg getProtoForCellType(BigDecimal t) { 132 return getProtoForType(t); 133 } 134 135 @Override 136 public BigDecimalMsg getProtoForPromotedType(BigDecimal s) { 137 return getProtoForType(s); 138 } 139 140 @Override 141 public BigDecimal getPromotedValueFromProto(BigDecimalMsg r) { 142 return Bytes.toBigDecimal(r.getBigdecimalMsg().toByteArray()); 143 } 144 145 @Override 146 public BigDecimal getCellValueFromProto(BigDecimalMsg q) { 147 return Bytes.toBigDecimal(q.getBigdecimalMsg().toByteArray()); 148 } 149}