All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cloudgraph.hbase.scan.RealLiteral Maven / Gradle / Ivy

Go to download

CloudGraph(tm) is a suite of Service Data Object (SDO) 2.1 services designed for relational and big-table style "cloud" databases, such as HBase and others.

There is a newer version: 2.0.4
Show newest version
/**
 *        CloudGraph Community Edition (CE) License
 * 
 * This is a community release of CloudGraph, a dual-license suite of
 * Service Data Object (SDO) 2.1 services designed for relational and 
 * big-table style "cloud" databases, such as HBase and others. 
 * This particular copy of the software is released under the 
 * version 2 of the GNU General Public License. CloudGraph was developed by 
 * TerraMeta Software, Inc.
 * 
 * Copyright (c) 2013, TerraMeta Software, Inc. All rights reserved.
 * 
 * General License information can be found below.
 * 
 * This distribution may include materials developed by third
 * parties. For license and attribution notices for these
 * materials, please refer to the documentation that accompanies
 * this distribution (see the "Licenses for Third-Party Components"
 * appendix) or view the online documentation at 
 * . 
 */
package org.cloudgraph.hbase.scan;

import java.math.BigDecimal;
import java.util.Arrays;

import org.cloudgraph.config.UserDefinedRowKeyFieldConfig;
import org.plasma.query.model.RelationalOperator;
import org.plasma.sdo.DataFlavor;
import org.plasma.sdo.DataType;
import org.plasma.sdo.PlasmaType;

import commonj.sdo.Type;

/**
 * A real data "flavor" specific literal class used to abstract 
 * the complexities involved in assembling the various 
 * segments and fields of composite (scan start/stop) row keys 
 * under various relational and logical operator and
 * various configurable composite key-field hashing, formatting, padding 
 * and other features. A real literal does not contain or involve wildcards but
 * nevertheless may "participate" in a fuzzy scan as part of a composite row key and
 * therefore implements {@link FuzzyRowKeyLiteral} supplying only default key and
 * info bytes.  
 * 
 * 
 * @see org.cloudgraph.config.TableConfig
 * @see org.cloudgraph.hbase.service.HBaseDataConverter
 * @author Scott Cinnamond
 * @since 0.5
 */
public class RealLiteral extends ScanLiteral 
    implements PartialRowKeyLiteral, FuzzyRowKeyLiteral, CompleteRowKeyLiteral {

	public static final float INCREMENT_FLOAT = Float.MIN_VALUE;
	public static final double INCREMENT_DOUBLE = Double.MIN_VALUE;
	public static final BigDecimal INCREMENT_DECIMAL = BigDecimal.valueOf(Double.MIN_VALUE);

	public RealLiteral(String literal,
			PlasmaType rootType,
			RelationalOperator relationalOperator,
			UserDefinedRowKeyFieldConfig fieldConfig) {
		super(literal, rootType, relationalOperator, 
			  fieldConfig);
	}
	
	/**
	 * Returns the "start row" bytes 
	 * used to represent "equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 * @return the "start row" bytes 
	 * used to represent "equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 */
	public byte[] getEqualsStartBytes() {
		byte[] startBytes = null;
		Object startValue = this.dataConverter.convert(property.getType(), this.literal);
		String startValueStr = this.dataConverter.toString(property.getType(), startValue);
		if (this.fieldConfig.isHash()) {
			startBytes = this.hashing.toStringBytes(startValueStr);
			startBytes = this.padding.pad(startBytes, 
					this.fieldConfig.getMaxLength(), 
					DataFlavor.integral);
		}
		else {
			startBytes = startValueStr.getBytes(this.charset);
			startBytes = this.padding.pad(startBytes, 
					this.fieldConfig.getMaxLength(), 
					this.fieldConfig.getDataFlavor());
		}
		return startBytes;
	}
	
	/**
	 * Returns the "stop row" bytes 
	 * used to represent "equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 * @return the "stop row" bytes 
	 * used to represent "equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 */
	public byte[] getEqualsStopBytes() {
		byte[] stopBytes = null;
		Object value = this.dataConverter.convert(property.getType(), this.literal);
		if (this.fieldConfig.isHash()) {
			String stopValueStr = incrementHash(property.getType(), value);
			stopBytes = stopValueStr.getBytes(this.charset);
			stopBytes = this.padding.pad(stopBytes, 
					this.fieldConfig.getMaxLength(), 
					DataFlavor.integral);
		}
		else {
			String stopValueStr = increment(property.getType(), value);
			stopBytes = stopValueStr.getBytes(this.charset);
			stopBytes = this.padding.pad(stopBytes, 
					this.fieldConfig.getMaxLength(), 
					this.fieldConfig.getDataFlavor());
		}
		return stopBytes;
	}	
	
	/**
	 * Returns the "start row" bytes 
	 * used to represent "greater than" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 * @return the "start row" bytes 
	 * used to represent "greater than" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 */
	public byte[] getGreaterThanStartBytes() {
		byte[] startBytes = null;
		Object value = this.dataConverter.convert(property.getType(), this.literal);
		if (this.fieldConfig.isHash()) {
			String startValueStr = incrementHash(property.getType(), value);
			startBytes = startValueStr.getBytes(this.charset);
			startBytes = this.padding.pad(startBytes, 
					this.fieldConfig.getMaxLength(), 
					DataFlavor.integral);
		}
		else {
			String startValueStr = increment(property.getType(), value);
			startBytes = startValueStr.getBytes(this.charset);
			startBytes = this.padding.pad(startBytes, 
					this.fieldConfig.getMaxLength(), 
					this.fieldConfig.getDataFlavor());
		}
		return startBytes;
	}
	
	/**
	 * Returns the "stop row" bytes 
	 * used to represent "greater than" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 * @return the "stop row" bytes 
	 * used to represent "greater than" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 */
	public byte[] getGreaterThanStopBytes() {
	    return new byte[0];
	}
	
	/**
	 * Returns the "start row" bytes 
	 * used to represent "greater than equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 * @return the "start row" bytes 
	 * used to represent "greater than equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 */
	public byte[] getGreaterThanEqualStartBytes() {
		byte[] startBytes = null;
		Object startValue = this.dataConverter.convert(property.getType(), this.literal);
		String startValueStr = this.dataConverter.toString(property.getType(), startValue);
		if (fieldConfig.isHash()) {
			startBytes = this.hashing.toStringBytes(startValueStr);
			startBytes = this.padding.pad(startBytes, 
					this.fieldConfig.getMaxLength(), 
					DataFlavor.integral);
		}
		else {
			startBytes = startValueStr.getBytes(this.charset);
			startBytes = this.padding.pad(startBytes, 
					this.fieldConfig.getMaxLength(), 
					this.fieldConfig.getDataFlavor());
		}
		return startBytes;
	}
	
	/**
	 * Returns the "stop row" bytes 
	 * used to represent "greater than equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 * @return the "stop row" bytes 
	 * used to represent "greater than equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 */
	public byte[] getGreaterThanEqualStopBytes() {
	    return new byte[0];
	}
	
	/**
	 * Returns the "start row" bytes 
	 * used to represent "less than" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 * @return the "start row" bytes 
	 * used to represent "less than" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 */	
	public byte[] getLessThanStartBytes() {
	    return new byte[0];
	}
	
	/**
	 * Returns the "stop row" bytes 
	 * used to represent "less than" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 * @return the "stop row" bytes 
	 * used to represent "less than" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 */	
	public byte[] getLessThanStopBytes() {
		byte[] stopBytes = null;
		Object stopValue = this.dataConverter.convert(property.getType(), this.literal);
		// Note: in HBase the stop row is exclusive, so just use
		// the literal value, no need to decrement it
		String stopValueStr = this.dataConverter.toString(property.getType(), stopValue);
		if (fieldConfig.isHash()) {
			stopBytes = this.hashing.toStringBytes(stopValueStr);
			stopBytes = this.padding.pad(stopBytes, 
					this.fieldConfig.getMaxLength(), 
					DataFlavor.integral);
		}
		else {
			stopBytes = stopValueStr.getBytes(this.charset);
			stopBytes = this.padding.pad(stopBytes, 
					this.fieldConfig.getMaxLength(), 
					this.fieldConfig.getDataFlavor());
		}
		return stopBytes;
	}
	
	/**
	 * Returns the "start row" bytes 
	 * used to represent "less than equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 * @return the "start row" bytes 
	 * used to represent "less than equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 */	
	public byte[] getLessThanEqualStartBytes() {
	    return new byte[0];
	}
	
	/**
	 * Returns the "stop row" bytes 
	 * used to represent "less than equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 * @return the "stop row" bytes 
	 * used to represent "less than equals" relational operator 
	 * under an HBase partial row-key scan for this real (data flavor) literal under 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 */	
	public byte[] getLessThanEqualStopBytes() {
		byte[] stopBytes = null;
		Object value = this.dataConverter.convert(property.getType(), this.literal);
		if (this.fieldConfig.isHash()) {
			String stopValueStr = incrementHash(property.getType(), value);
			stopBytes = stopValueStr.getBytes(this.charset);
			stopBytes = this.padding.pad(stopBytes, 
					this.fieldConfig.getMaxLength(), 
					DataFlavor.integral);
		}
		else {
			String stopValueStr = increment(property.getType(), value);
			stopBytes = stopValueStr.getBytes(this.charset);
			stopBytes = this.padding.pad(stopBytes, 
					this.fieldConfig.getMaxLength(), 
					this.fieldConfig.getDataFlavor());
		}
		return stopBytes;
	}
	
	/**
	 * Returns the bytes 
	 * used to represent an "equals" relational operator 
	 * for a specific composite row key field, under an HBase 'Get' operation for 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 * @return the bytes 
	 * used to represent an "equals" relational operator 
	 * for a specific composite row key field, under an HBase 'Get' operation for 
	 * the various optionally configurable hashing, 
	 * formatting and padding features.
	 */
	@Override
	public byte[] getEqualsBytes() {
		return getEqualsStartBytes();
	}
	
	@Override
	public byte[] getFuzzyKeyBytes() {
		return getEqualsStartBytes();
	}

	@Override
	public byte[] getFuzzyInfoBytes() {
		byte[] infoBytes = new byte[this.fieldConfig.getMaxLength()];
		Arrays.fill(infoBytes, (byte)0); // fixed char 
		return infoBytes;
	}
	
	private String incrementHash(Type type, Object value) {
		String valueStr = this.dataConverter.toString(property.getType(), value);
		String result = this.hashing.toString(valueStr, HASH_INCREMENT);
		return result;
	}
	
	private String increment(Type type, Object value) {
		String result = "";
        DataType sourceDataType = DataType.valueOf(type.getName());
        switch (sourceDataType) {
        case Float:
    		Float floatValue = this.dataConverter.toFloat(property.getType(), value);
		    int intBits = Float.floatToRawIntBits(floatValue.floatValue());
		    intBits++;
		    Float floatResult = Float.valueOf(Float.intBitsToFloat(intBits));
		    result = this.dataConverter.toString(type, floatResult);
    		break;
        case Double:
    		Double doubleValue = this.dataConverter.toDouble(property.getType(), value);
		    long longBits = Double.doubleToRawLongBits(doubleValue.doubleValue());
		    longBits++;
		    Double doubleResult = Double.valueOf(Double.longBitsToDouble(longBits));
		    result = this.dataConverter.toString(type, doubleResult);
    		break;
        case Decimal:        	        	
    		BigDecimal decimalValue = this.dataConverter.toDecimal(property.getType(), value);
    		//FIXME: loss of precision
    		double temp = decimalValue.doubleValue();
		    longBits = Double.doubleToRawLongBits(temp);
		    longBits++;
		    doubleResult = Double.valueOf(Double.longBitsToDouble(longBits));
		    result = this.dataConverter.toString(type, doubleResult);
    		break;
        default:
        	throw new ScanException("expected real (Float, Double, Decinal)datatype not, "
        			+ sourceDataType.name());
        }
        return result;
	}



}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy