View Javadoc

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  package org.apache.hadoop.hbase.client.coprocessor;
20  
21  import java.io.IOException;
22  import java.math.BigDecimal;
23  import java.math.RoundingMode;
24  
25  import org.apache.hadoop.hbase.Cell;
26  import org.apache.hadoop.hbase.CellUtil;
27  import org.apache.hadoop.hbase.classification.InterfaceAudience;
28  import org.apache.hadoop.hbase.coprocessor.ColumnInterpreter;
29  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.BigDecimalMsg;
30  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.EmptyMsg;
31  import org.apache.hadoop.hbase.util.ByteStringer;
32  import org.apache.hadoop.hbase.util.Bytes;
33  
34  /**
35   * ColumnInterpreter for doing Aggregation's with BigDecimal columns. This class
36   * is required at the RegionServer also.
37   *
38   */
39  @InterfaceAudience.Private
40  public class BigDecimalColumnInterpreter extends ColumnInterpreter<BigDecimal, BigDecimal,
41    EmptyMsg, BigDecimalMsg, BigDecimalMsg> {
42  
43    @Override
44    public BigDecimal getValue(byte[] colFamily, byte[] colQualifier, Cell kv)
45        throws IOException {
46      if (kv == null || CellUtil.cloneValue(kv) == null) {
47        return null;
48      }
49      return CellUtil.getValueAsBigDecimal(kv).setScale(2, RoundingMode.HALF_EVEN);
50    }
51  
52    @Override
53    public BigDecimal add(BigDecimal bd1, BigDecimal bd2) {
54      if (bd1 == null ^ bd2 == null) {
55        return (bd1 == null) ? bd2 : bd1; // either of one is null.
56      }
57      if (bd1 == null) {
58        return null;
59      }
60      return bd1.add(bd2);
61    }
62  
63    @Override
64    public int compare(final BigDecimal bd1, final BigDecimal bd2) {
65      if (bd1 == null ^ bd2 == null) {
66        return bd1 == null ? -1 : 1; // either of one is null.
67      }
68      if (bd1 == null) {
69        return 0; // both are null
70      }
71      return bd1.compareTo(bd2); // natural ordering.
72    }
73  
74    @Override
75    public BigDecimal getMaxValue() {
76      return BigDecimal.valueOf(Double.MAX_VALUE);
77    }
78  
79    @Override
80    public BigDecimal increment(BigDecimal bd) {
81      return bd == null ? null : (bd.add(BigDecimal.ONE));
82    }
83  
84    @Override
85    public BigDecimal multiply(BigDecimal bd1, BigDecimal bd2) {
86      return (bd1 == null || bd2 == null) ? null : bd1.multiply(bd2)
87          .setScale(2,RoundingMode.HALF_EVEN);
88    }
89  
90    @Override
91    public BigDecimal getMinValue() {
92      return BigDecimal.valueOf(Double.MIN_VALUE);
93    }
94  
95    @Override
96    public double divideForAvg(BigDecimal bd1, Long l2) {
97      return (l2 == null || bd1 == null) ? Double.NaN : (bd1.doubleValue() / l2
98          .doubleValue());
99    }
100 
101   @Override
102   public BigDecimal castToReturnType(BigDecimal bd) {
103     return bd;
104   }
105 
106   @Override
107   public BigDecimal castToCellType(BigDecimal bd) {
108     return bd;
109   }
110 
111   @Override
112   public EmptyMsg getRequestData() {
113     return EmptyMsg.getDefaultInstance();
114   }
115 
116   @Override
117   public void initialize(EmptyMsg msg) {
118     //nothing
119   }
120 
121   private BigDecimalMsg getProtoForType(BigDecimal t) {
122     BigDecimalMsg.Builder builder = BigDecimalMsg.newBuilder();
123     return builder.setBigdecimalMsg(ByteStringer.wrap(Bytes.toBytes(t))).build();
124   }
125   
126   @Override
127   public BigDecimalMsg getProtoForCellType(BigDecimal t) {
128     return getProtoForType(t);
129   }
130 
131   @Override
132   public BigDecimalMsg getProtoForPromotedType(BigDecimal s) {
133     return getProtoForType(s);
134   }
135 
136   @Override
137   public BigDecimal getPromotedValueFromProto(BigDecimalMsg r) {
138     return Bytes.toBigDecimal(r.getBigdecimalMsg().toByteArray());
139   }
140 
141   @Override
142   public BigDecimal getCellValueFromProto(BigDecimalMsg q) {
143     return Bytes.toBigDecimal(q.getBigdecimalMsg().toByteArray());
144   }
145 }