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;
022
023import org.apache.hadoop.hbase.Cell;
024import org.apache.hadoop.hbase.HBaseInterfaceAudience;
025import org.apache.hadoop.hbase.PrivateCellUtil;
026import org.apache.yetus.audience.InterfaceAudience;
027import org.apache.yetus.audience.InterfaceStability;
028import org.apache.hadoop.hbase.coprocessor.ColumnInterpreter;
029import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.DoubleMsg;
030import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.EmptyMsg;
031import org.apache.hadoop.hbase.util.Bytes;
032
033/**
034 * a concrete column interpreter implementation. The cell value is a Double value
035 * and its promoted data type is also a Double value. For computing aggregation
036 * function, this class is used to find the datatype of the cell value. Client
037 * is supposed to instantiate it and passed along as a parameter. See
038 * TestDoubleColumnInterpreter methods for its sample usage.
039 * Its methods handle null arguments gracefully. 
040 */
041@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
042@InterfaceStability.Evolving
043public class DoubleColumnInterpreter extends ColumnInterpreter<Double, Double, 
044      EmptyMsg, DoubleMsg, DoubleMsg>{
045 
046  @Override
047  public Double getValue(byte[] colFamily, byte[] colQualifier, Cell c)
048      throws IOException {
049    if (c == null || c.getValueLength() != Bytes.SIZEOF_DOUBLE)
050      return null;
051    return PrivateCellUtil.getValueAsDouble(c);
052  }
053
054  @Override
055  public Double add(Double d1, Double d2) {
056    if (d1 == null || d2 == null) {
057      return (d1 == null) ? d2 : d1; 
058    }
059    return d1 + d2;
060  }
061
062  @Override
063  public int compare(final Double d1, final Double d2) {
064    if (d1 == null ^ d2 == null) {
065      return d1 == null ? -1 : 1; // either of one is null.
066    } else if (d1 == null)
067      return 0; // both are null
068    return d1.compareTo(d2); // natural ordering.
069  }
070
071  @Override
072  public Double getMaxValue() {
073    return Double.MAX_VALUE;
074  }
075
076  @Override
077  public Double increment(Double o) {
078    return o == null ? null : (o + 1.00d);
079  }
080
081  @Override
082  public Double multiply(Double d1, Double d2) {
083    return (d1 == null || d2 == null) ? null : d1 * d2;
084  }
085
086  @Override
087  public Double getMinValue() {
088    return Double.MIN_VALUE;
089  }
090
091  @Override
092  public double divideForAvg(Double d1, Long l2) {
093    return (l2 == null || d1 == null) ? Double.NaN : (d1.doubleValue() / l2
094        .doubleValue());
095  }
096
097  @Override
098  public Double castToReturnType(Double o) {
099    return o;
100  }
101
102  @Override
103  public Double castToCellType(Double d) {
104    return d;
105  }
106
107  @Override
108  public EmptyMsg getRequestData() {
109    return EmptyMsg.getDefaultInstance();
110  }
111
112  @Override
113  public void initialize(EmptyMsg msg) {
114    //nothing 
115  }
116
117  @Override
118  public DoubleMsg getProtoForCellType(Double t) {
119    DoubleMsg.Builder builder = DoubleMsg.newBuilder();
120    return builder.setDoubleMsg(t).build();
121  }
122
123  @Override
124  public DoubleMsg getProtoForPromotedType(Double s) {
125    DoubleMsg.Builder builder = DoubleMsg.newBuilder();
126    return builder.setDoubleMsg(s).build();
127  }
128
129  @Override
130  public Double getPromotedValueFromProto(DoubleMsg r) {
131    return r.getDoubleMsg();
132  }
133
134  @Override
135  public Double getCellValueFromProto(DoubleMsg q) {
136    return q.getDoubleMsg();
137  }
138}