Package org.apache.expreval.expr.compare

Source Code of org.apache.expreval.expr.compare.NumberCompare

/*
* Copyright (c) 2011.  The Apache Software Foundation
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.expreval.expr.compare;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.expreval.client.NullColumnValueException;
import org.apache.expreval.client.ResultMissingColumnException;
import org.apache.expreval.expr.Operator;
import org.apache.expreval.expr.node.GenericValue;
import org.apache.expreval.expr.node.NumberValue;
import org.apache.expreval.expr.var.DelegateColumn;
import org.apache.expreval.expr.var.GenericColumn;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.WritableByteArrayComparable;
import org.apache.hadoop.hbase.hbql.client.HBqlException;
import org.apache.hadoop.hbase.hbql.impl.HConnectionImpl;
import org.apache.hadoop.hbase.hbql.impl.Utils;
import org.apache.hadoop.hbase.hbql.io.IO;
import org.apache.hadoop.hbase.hbql.mapping.FieldType;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

public class NumberCompare extends GenericCompare {

    private static final Log LOG = LogFactory.getLog(NumberCompare.class);

    public NumberCompare(final GenericValue arg0, final Operator operator, final GenericValue arg1) {
        super(arg0, operator, arg1);
    }

    public Class<? extends GenericValue> validateTypes(final GenericValue parentExpr,
                                                       final boolean allowCollections) throws HBqlException {
        return this.validateType(NumberValue.class);
    }

    public Boolean getValue(final HConnectionImpl conn, final Object object) throws HBqlException,
                                                                                    ResultMissingColumnException,
                                                                                    NullColumnValueException {
        final Object obj0 = this.getValue(0, conn, object);
        final Object obj1 = this.getValue(1, conn, object);

        this.validateNumericArgTypes(obj0, obj1);

        if (!this.useDecimal()) {

            final long val0 = ((Number)obj0).longValue();
            final long val1 = ((Number)obj1).longValue();

            switch (this.getOperator()) {
                case EQ:
                    return val0 == val1;
                case GT:
                    return val0 > val1;
                case GTEQ:
                    return val0 >= val1;
                case LT:
                    return val0 < val1;
                case LTEQ:
                    return val0 <= val1;
                case NOTEQ:
                    return val0 != val1;
                default:
                    throw new HBqlException("Invalid operator: " + this.getOperator());
            }
        }
        else {

            final double val0 = ((Number)obj0).doubleValue();
            final double val1 = ((Number)obj1).doubleValue();

            switch (this.getOperator()) {
                case EQ:
                    return val0 == val1;
                case GT:
                    return val0 > val1;
                case GTEQ:
                    return val0 >= val1;
                case LT:
                    return val0 < val1;
                case LTEQ:
                    return val0 <= val1;
                case NOTEQ:
                    return val0 != val1;
                default:
                    throw new HBqlException("Invalid operator: " + this.getOperator());
            }
        }
    }

    public Filter getFilter() throws HBqlException {

        this.validateArgsForCompareFilter();

        final GenericColumn<? extends GenericValue> column;
        final Object constant;
        final CompareFilter.CompareOp compareOp;
        final WritableByteArrayComparable comparator;

        if (this.getExprArg(0).isAColumnReference()) {
            column = ((DelegateColumn)this.getExprArg(0)).getTypedColumn();
            constant = this.getConstantValue(1);
            compareOp = this.getOperator().getCompareOpLeft();
        }
        else {
            column = ((DelegateColumn)this.getExprArg(1)).getTypedColumn();
            constant = this.getConstantValue(0);
            compareOp = this.getOperator().getCompareOpRight();
        }

        this.validateNumericArgTypes(constant);

        if (!this.useDecimal()) {
            final long val = ((Number)constant).longValue();
            comparator = new LongComparable(column.getColumnAttrib().getFieldType(), val);
        }
        else {
            final double val = ((Number)constant).doubleValue();
            comparator = new DoubleComparable(column.getColumnAttrib().getFieldType(), val);
        }

        return this.newSingleColumnValueFilter(column.getColumnAttrib(), compareOp, comparator);
    }

    private static abstract class NumberComparable<T> extends GenericComparable<T> {

        private FieldType fieldType;

        protected void setFieldType(final FieldType fieldType) {
            this.fieldType = fieldType;
        }

        protected FieldType getFieldType() {
            return this.fieldType;
        }

        protected void setValueInBytes(final Number val) throws IOException {
            try {
                this.setValueInBytes(IO.getSerialization().getNumberEqualityBytes(this.getFieldType(), val));
            }
            catch (HBqlException e) {
                throw new IOException(e.getMessage());
            }
        }
    }

    private static class LongComparable extends NumberComparable<Long> {

        public LongComparable() {
        }

        public LongComparable(final FieldType fieldType, final long value) {
            this.setFieldType(fieldType);
            this.setTypedValue(value);
        }

        public int compareTo(final byte[] bytes) {

            if (this.equalValues(bytes))
                return 0;

            try {
                long columnValue = IO.getSerialization().getNumberFromBytes(this.getFieldType(), bytes).longValue();
                // Test for equality again in case the byte[] lengths were different above
                final long val = this.getTypedValue();
                if (columnValue == val)
                    return 0;
                else
                    return (columnValue > val) ? -1 : 1;
            }
            catch (HBqlException e) {
                e.printStackTrace();
                Utils.logException(LOG, e);
                return 1;
            }
        }

        public void write(final DataOutput dataOutput) throws IOException {
            dataOutput.writeUTF(this.getFieldType().name());
            dataOutput.writeLong(this.getTypedValue());
        }

        public void readFields(final DataInput dataInput) throws IOException {
            this.setFieldType(FieldType.valueOf(dataInput.readUTF()));
            this.setTypedValue(dataInput.readLong());

            this.setValueInBytes(this.getTypedValue());
        }
    }

    private static class DoubleComparable extends NumberComparable<Double> {

        public DoubleComparable() {
        }

        public DoubleComparable(final FieldType fieldType, final double value) {
            this.setFieldType(fieldType);
            this.setTypedValue(value);
        }

        public int compareTo(final byte[] bytes) {

            if (this.equalValues(bytes))
                return 0;

            try {
                double columnValue = IO.getSerialization().getNumberFromBytes(this.getFieldType(), bytes).doubleValue();
                // Test for equality again in case the byte[] lengths were different above
                final double val = this.getTypedValue();
                if (columnValue == val)
                    return 0;
                else
                    return (columnValue > val) ? -1 : 1;
            }
            catch (HBqlException e) {
                e.printStackTrace();
                Utils.logException(LOG, e);
                return 1;
            }
        }

        public void write(final DataOutput dataOutput) throws IOException {
            dataOutput.writeUTF(this.getFieldType().name());
            dataOutput.writeDouble(this.getTypedValue());
        }

        public void readFields(final DataInput dataInput) throws IOException {
            this.setFieldType(FieldType.valueOf(dataInput.readUTF()));
            this.setTypedValue(dataInput.readDouble());

            this.setValueInBytes(this.getTypedValue());
        }
    }
}
TOP

Related Classes of org.apache.expreval.expr.compare.NumberCompare

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.