View Javadoc

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.types;
19  
20  import java.math.BigDecimal;
21  import java.math.BigInteger;
22  
23  import org.apache.hadoop.hbase.classification.InterfaceAudience;
24  import org.apache.hadoop.hbase.classification.InterfaceStability;
25  import org.apache.hadoop.hbase.util.Order;
26  import org.apache.hadoop.hbase.util.OrderedBytes;
27  import org.apache.hadoop.hbase.util.PositionedByteRange;
28  import org.apache.hadoop.hbase.util.SimplePositionedMutableByteRange;
29  
30  /**
31   * An {@link Number} of arbitrary precision and variable-length encoding. The
32   * resulting length of encoded values is determined by the numerical (base
33   * 100) precision, not absolute value. Use this data type anywhere you would
34   * expect to use a {@code DECIMAL} type, a {@link BigDecimal}, a
35   * {@link BigInteger}, or any time you've parsed floating precision values
36   * from text. Built on {@link OrderedBytes#encodeNumeric(PositionedByteRange, BigDecimal, Order)}.
37   */
38  @InterfaceAudience.Public
39  @InterfaceStability.Evolving
40  public class OrderedNumeric extends OrderedBytesBase<Number> {
41  
42    public static final OrderedNumeric ASCENDING = new OrderedNumeric(Order.ASCENDING);
43    public static final OrderedNumeric DESCENDING = new OrderedNumeric(Order.DESCENDING);
44  
45    protected OrderedNumeric(Order order) { super(order); }
46  
47    @Override
48    public int encodedLength(Number val) {
49      // TODO: this could be done better.
50      PositionedByteRange buff = new SimplePositionedMutableByteRange(100);
51      return encode(buff, val);
52    }
53  
54    @Override
55    public Class<Number> encodedClass() { return Number.class; }
56  
57    @Override
58    public Number decode(PositionedByteRange src) {
59      if (OrderedBytes.isNumericInfinite(src) || OrderedBytes.isNumericNaN(src)) {
60        return OrderedBytes.decodeNumericAsDouble(src);
61      }
62      return OrderedBytes.decodeNumericAsBigDecimal(src);
63    }
64  
65    @Override
66    public int encode(PositionedByteRange dst, Number val) {
67      if (null == val) {
68        return OrderedBytes.encodeNull(dst, order);
69      } else if (val instanceof BigDecimal) {
70        return OrderedBytes.encodeNumeric(dst, (BigDecimal) val, order);
71      } else if (val instanceof BigInteger) {
72        return OrderedBytes.encodeNumeric(dst, new BigDecimal((BigInteger) val), order);
73      } else if (val instanceof Double || val instanceof Float) {
74        return OrderedBytes.encodeNumeric(dst, val.doubleValue(), order);
75      } else {
76        // TODO: other instances of Numeric to consider?
77        return OrderedBytes.encodeNumeric(dst, val.longValue(), order);
78      }
79    }
80  
81    /**
82     * Read a {@code long} value from the buffer {@code src}.
83     */
84    public long decodeLong(PositionedByteRange src) {
85      return OrderedBytes.decodeNumericAsLong(src);
86    }
87  
88    /**
89     * Write instance {@code val} into buffer {@code dst}.
90     */
91    public int encodeLong(PositionedByteRange dst, long val) {
92      return OrderedBytes.encodeNumeric(dst, val, order);
93    }
94  
95    /**
96     * Read a {@code double} value from the buffer {@code src}.
97     */
98    public double decodeDouble(PositionedByteRange src) {
99      return OrderedBytes.decodeNumericAsLong(src);
100   }
101 
102   /**
103    * Write instance {@code val} into buffer {@code dst}.
104    */
105   public int encodeDouble(PositionedByteRange dst, double val) {
106     return OrderedBytes.encodeNumeric(dst, val, order);
107   }
108 }