Package com.salesforce.phoenix.join

Source Code of com.salesforce.phoenix.join.ScanProjector

/*******************************************************************************
* Copyright (c) 2013, Salesforce.com, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     Redistributions of source code must retain the above copyright notice,
*     this list of conditions and the following disclaimer.
*     Redistributions in binary form must reproduce the above copyright notice,
*     this list of conditions and the following disclaimer in the documentation
*     and/or other materials provided with the distribution.
*     Neither the name of Salesforce.com nor the names of its contributors may
*     be used to endorse or promote products derived from this software without
*     specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
package com.salesforce.phoenix.join;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;

import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.WritableUtils;

import com.salesforce.phoenix.compile.JoinCompiler.ProjectedPTableWrapper;
import com.salesforce.phoenix.expression.Expression;
import com.salesforce.phoenix.expression.ExpressionType;
import com.salesforce.phoenix.schema.KeyValueSchema;
import com.salesforce.phoenix.schema.PColumn;
import com.salesforce.phoenix.schema.ValueBitSet;
import com.salesforce.phoenix.schema.KeyValueSchema.KeyValueSchemaBuilder;
import com.salesforce.phoenix.schema.tuple.Tuple;
import com.salesforce.phoenix.util.KeyValueUtil;
import com.salesforce.phoenix.util.SchemaUtil;

public class ScanProjector {   
    public static final byte[] VALUE_COLUMN_FAMILY = Bytes.toBytes("_v");
    public static final byte[] VALUE_COLUMN_QUALIFIER = new byte[0];
   
    private static final String SCAN_PROJECTOR = "scanProjector";
   
    private final KeyValueSchema schema;
    private final Expression[] expressions;
    private ValueBitSet valueSet;
    private final ImmutableBytesWritable ptr = new ImmutableBytesWritable();
   
    public ScanProjector(ProjectedPTableWrapper projected) {
      List<PColumn> columns = projected.getTable().getColumns();
      expressions = new Expression[columns.size() - projected.getTable().getPKColumns().size()];
      // we do not count minNullableIndex for we might do later merge.
      KeyValueSchemaBuilder builder = new KeyValueSchemaBuilder(0);
      int i = 0;
        for (PColumn column : projected.getTable().getColumns()) {
          if (!SchemaUtil.isPKColumn(column)) {
            builder.addField(column);
            expressions[i++] = projected.getSourceExpression(column);
          }
        }
        schema = builder.build();
        valueSet = ValueBitSet.newInstance(schema);
    }
   
    private ScanProjector(KeyValueSchema schema, Expression[] expressions) {
      this.schema = schema;
      this.expressions = expressions;
      this.valueSet = ValueBitSet.newInstance(schema);
    }
   
    public void setValueBitSet(ValueBitSet bitSet) {
        this.valueSet = bitSet;
    }
   
    public static void serializeProjectorIntoScan(Scan scan, ScanProjector projector) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        try {
            DataOutputStream output = new DataOutputStream(stream);
            projector.schema.write(output);
            int count = projector.expressions.length;
            WritableUtils.writeVInt(output, count);
            for (int i = 0; i < count; i++) {
              WritableUtils.writeVInt(output, ExpressionType.valueOf(projector.expressions[i]).ordinal());
              projector.expressions[i].write(output);
            }
            scan.setAttribute(SCAN_PROJECTOR, stream.toByteArray());
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                stream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
       
    }
   
    public static ScanProjector deserializeProjectorFromScan(Scan scan) {
        byte[] proj = scan.getAttribute(SCAN_PROJECTOR);
        if (proj == null) {
            return null;
        }
        ByteArrayInputStream stream = new ByteArrayInputStream(proj);
        try {
            DataInputStream input = new DataInputStream(stream);
            KeyValueSchema schema = new KeyValueSchema();
            schema.readFields(input);
            int count = WritableUtils.readVInt(input);
            Expression[] expressions = new Expression[count];
            for (int i = 0; i < count; i++) {
              int ordinal = WritableUtils.readVInt(input);
              expressions[i] = ExpressionType.values()[ordinal].newInstance();
              expressions[i].readFields(input);
            }
            return new ScanProjector(schema, expressions);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                stream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
   
    public static class ProjectedValueTuple implements Tuple {
        private ImmutableBytesWritable keyPtr = new ImmutableBytesWritable();
        private long timestamp;
        private byte[] projectedValue;
        private int bitSetLen;
        private KeyValue keyValue;

        private ProjectedValueTuple(byte[] keyBuffer, int keyOffset, int keyLength, long timestamp, byte[] projectedValue, int bitSetLen) {
            this.keyPtr.set(keyBuffer, keyOffset, keyLength);
            this.timestamp = timestamp;
            this.projectedValue = projectedValue;
            this.bitSetLen = bitSetLen;
        }
       
        public ImmutableBytesWritable getKeyPtr() {
            return keyPtr;
        }
       
        public long getTimestamp() {
            return timestamp;
        }
       
        public byte[] getProjectedValue() {
            return projectedValue;
        }
       
        public int getBitSetLength() {
            return bitSetLen;
        }
       
        @Override
        public void getKey(ImmutableBytesWritable ptr) {
            ptr.set(keyPtr.get(), keyPtr.getOffset(), keyPtr.getLength());
        }

        @Override
        public KeyValue getValue(int index) {
            if (index != 0) {
                throw new IndexOutOfBoundsException(Integer.toString(index));
            }
            return getValue(VALUE_COLUMN_FAMILY, VALUE_COLUMN_QUALIFIER);
        }

        @Override
        public KeyValue getValue(byte[] family, byte[] qualifier) {
            if (keyValue == null) {
                keyValue = KeyValueUtil.newKeyValue(keyPtr.get(), keyPtr.getOffset(), keyPtr.getLength(),
                        VALUE_COLUMN_FAMILY, VALUE_COLUMN_QUALIFIER, timestamp, projectedValue, 0, projectedValue.length);
            }
            return keyValue;
        }

        @Override
        public boolean getValue(byte[] family, byte[] qualifier,
                ImmutableBytesWritable ptr) {
            ptr.set(projectedValue);
            return true;
        }

        @Override
        public boolean isImmutable() {
            return true;
        }

        @Override
        public int size() {
            return 1;
        }
    }
   
    public ProjectedValueTuple projectResults(Tuple tuple) {
      byte[] bytesValue = schema.toBytes(tuple, expressions, valueSet, ptr);
      KeyValue base = tuple.getValue(0);
        return new ProjectedValueTuple(base.getBuffer(), base.getRowOffset(), base.getRowLength(), base.getTimestamp(), bytesValue, valueSet.getEstimatedLength());
    }
   
    public static void decodeProjectedValue(Tuple tuple, ImmutableBytesWritable ptr) throws IOException {
      boolean b = tuple.getValue(VALUE_COLUMN_FAMILY, VALUE_COLUMN_QUALIFIER, ptr);
        if (!b)
            throw new IOException("Trying to decode a non-projected value.");
    }
   
    public static ProjectedValueTuple mergeProjectedValue(ProjectedValueTuple dest, KeyValueSchema destSchema, ValueBitSet destBitSet,
        Tuple src, KeyValueSchema srcSchema, ValueBitSet srcBitSet, int offset) throws IOException {
      ImmutableBytesWritable destValue = new ImmutableBytesWritable(dest.getProjectedValue());
      destBitSet.clear();
      destBitSet.or(destValue);
      int origDestBitSetLen = dest.getBitSetLength();
      ImmutableBytesWritable srcValue = new ImmutableBytesWritable();
      decodeProjectedValue(src, srcValue);
      srcBitSet.clear();
      srcBitSet.or(srcValue);
      int origSrcBitSetLen = srcBitSet.getEstimatedLength();
      for (int i = 0; i < srcBitSet.getMaxSetBit(); i++) {
        if (srcBitSet.get(i)) {
          destBitSet.set(offset + i);
        }
      }
      int destBitSetLen = destBitSet.getEstimatedLength();
      byte[] merged = new byte[destValue.getLength() - origDestBitSetLen + srcValue.getLength() - origSrcBitSetLen + destBitSetLen];
      int o = Bytes.putBytes(merged, 0, destValue.get(), destValue.getOffset(), destValue.getLength() - origDestBitSetLen);
      o = Bytes.putBytes(merged, o, srcValue.get(), srcValue.getOffset(), srcValue.getLength() - origSrcBitSetLen);
      destBitSet.toBytes(merged, o);
      ImmutableBytesWritable keyPtr = dest.getKeyPtr();
        return new ProjectedValueTuple(keyPtr.get(), keyPtr.getOffset(), keyPtr.getLength(), dest.getTimestamp(), merged, destBitSetLen);
    }
}
TOP

Related Classes of com.salesforce.phoenix.join.ScanProjector

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.