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