hive-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ser...@apache.org
Subject [10/17] hive git commit: HIVE-9824 : LLAP: Native Vectorization of Map Join (Matt McCline, reviewed by Sergey Shelukhin, Vikram Dixit K)
Date Wed, 22 Apr 2015 22:51:00 GMT
http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedHashTable.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedHashTable.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedHashTable.java
new file mode 100644
index 0000000..a2d4e4c
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedHashTable.java
@@ -0,0 +1,95 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hive.ql.exec.JoinUtil;
+import org.apache.hadoop.hive.ql.exec.persistence.BytesBytesMultiHashMap;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainerDirectAccess;
+import org.apache.hadoop.hive.ql.exec.persistence.ReusableGetAdaptorDirectAccess;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer.ReusableGetAdaptor;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinHashTable;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinHashTableResult;
+import org.apache.hadoop.hive.ql.metadata.HiveException;
+import org.apache.hadoop.hive.serde2.SerDeException;
+import org.apache.hadoop.io.BytesWritable;
+import org.apache.hadoop.io.Writable;
+
+/*
+ * Root interface for a vector map join hash table (which could be a hash map, hash multi-set, or
+ * hash set).
+ */
+public abstract class VectorMapJoinOptimizedHashTable implements VectorMapJoinHashTable {
+
+  private static final Log LOG = LogFactory.getLog(VectorMapJoinOptimizedMultiKeyHashMap.class.getName());
+
+  protected final MapJoinTableContainer originalTableContainer;
+  protected final MapJoinTableContainerDirectAccess containerDirectAccess;
+  protected final ReusableGetAdaptorDirectAccess adapatorDirectAccess;
+
+  public static class SerializedBytes {
+    byte[] bytes;
+    int offset;
+    int length;
+  }
+
+  @Override
+  public void putRow(BytesWritable currentKey, BytesWritable currentValue)
+      throws SerDeException, HiveException, IOException {
+
+    putRowInternal(currentKey, currentValue);
+  }
+
+  protected void putRowInternal(BytesWritable key, BytesWritable value)
+      throws SerDeException, HiveException, IOException {
+
+    containerDirectAccess.put((Writable) key, (Writable) value);
+  }
+
+  public JoinUtil.JoinResult doLookup(byte[] keyBytes, int keyOffset, int keyLength,
+          BytesBytesMultiHashMap.Result bytesBytesMultiHashMapResult,
+          VectorMapJoinHashTableResult hashTableResult) {
+
+    hashTableResult.forget();
+
+    JoinUtil.JoinResult joinResult =
+            adapatorDirectAccess.setDirect(keyBytes, keyOffset, keyLength,
+                bytesBytesMultiHashMapResult);
+    if (joinResult == JoinUtil.JoinResult.SPILL) {
+      hashTableResult.setSpillPartitionId(adapatorDirectAccess.directSpillPartitionId());
+    }
+
+    hashTableResult.setJoinResult(joinResult);
+
+    return joinResult;
+  }
+
+  public VectorMapJoinOptimizedHashTable(
+      MapJoinTableContainer originalTableContainer, ReusableGetAdaptor hashMapRowGetter) {
+
+    this.originalTableContainer = originalTableContainer;
+    containerDirectAccess = (MapJoinTableContainerDirectAccess) originalTableContainer;
+    adapatorDirectAccess = (ReusableGetAdaptorDirectAccess) hashMapRowGetter;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongCommon.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongCommon.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongCommon.java
new file mode 100644
index 0000000..60825ce
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongCommon.java
@@ -0,0 +1,171 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.optimized.VectorMapJoinOptimizedHashTable.SerializedBytes;
+import org.apache.hadoop.hive.ql.plan.VectorMapJoinDesc.HashTableKeyType;
+import org.apache.hadoop.hive.serde2.ByteStream.Output;
+import org.apache.hadoop.hive.serde2.binarysortable.fast.BinarySortableSerializeWrite;
+
+/*
+ * An single long value hash map based on the BytesBytesMultiHashMap.
+ *
+ * We serialize the long key into BinarySortable format into an output buffer accepted by
+ * BytesBytesMultiHashMap.
+ */
+public class VectorMapJoinOptimizedLongCommon {
+
+  private static final Log LOG = LogFactory.getLog(VectorMapJoinOptimizedLongCommon.class.getName());
+
+  private boolean isOuterJoin;
+
+  private HashTableKeyType hashTableKeyType;
+
+  // private BinarySortableDeserializeRead keyBinarySortableDeserializeRead;
+
+  private BinarySortableSerializeWrite keyBinarySortableSerializeWrite;
+
+  private transient Output output;
+
+  private transient SerializedBytes serializedBytes;
+
+  // protected boolean useMinMax;
+  protected long min;
+  protected long max;
+
+  public boolean useMinMax() {
+    return false;
+  }
+
+  public long min() {
+    return min;
+  }
+
+  public long max() {
+    return max;
+  }
+
+  /*
+   * For now, just use MapJoinBytesTableContainer / HybridHashTableContainer directly.
+
+  public void adaptPutRow(VectorMapJoinOptimizedHashTable hashTable,
+      BytesWritable currentKey, BytesWritable currentValue)
+      throws SerDeException, HiveException, IOException {
+
+    if (useMinMax) {
+      // Peek at the BinarySortable key to extract the long so we can determine min and max.
+      byte[] keyBytes = currentKey.getBytes();
+      int keyLength = currentKey.getLength();
+      keyBinarySortableDeserializeRead.set(keyBytes, 0, keyLength);
+      if (keyBinarySortableDeserializeRead.readCheckNull()) {
+        if (isOuterJoin) {
+          return;
+        } else {
+          // For inner join, we expect all NULL values to have been filtered out before now.
+          throw new HiveException("Unexpected NULL");
+        }
+      }
+      long key = 0;
+      switch (hashTableKeyType) {
+      case BOOLEAN:
+        key = (keyBinarySortableDeserializeRead.readBoolean() ? 1 : 0);
+        break;
+      case BYTE:
+        key = (long) keyBinarySortableDeserializeRead.readByte();
+        break;
+      case SHORT:
+        key = (long) keyBinarySortableDeserializeRead.readShort();
+        break;
+      case INT:
+        key = (long) keyBinarySortableDeserializeRead.readInt();
+        break;
+      case LONG:
+        key = keyBinarySortableDeserializeRead.readLong();
+        break;
+      default:
+        throw new RuntimeException("Unexpected hash table key type " + hashTableKeyType.name());
+      }
+      if (key < min) {
+        min = key;
+      }
+      if (key > max) {
+        max = key;
+      }
+
+      // byte[] bytes = Arrays.copyOf(currentKey.get(), currentKey.getLength());
+      // LOG.info("VectorMapJoinOptimizedLongCommon adaptPutRow key " + key + " min " + min + " max " + max + " hashTableKeyType " + hashTableKeyType.name() + " hex " + Hex.encodeHexString(bytes));
+
+    }
+
+    hashTable.putRowInternal(currentKey, currentValue);
+  }
+  */
+
+  public SerializedBytes serialize(long key) throws IOException {
+    keyBinarySortableSerializeWrite.reset();
+
+    switch (hashTableKeyType) {
+    case BOOLEAN:
+      keyBinarySortableSerializeWrite.writeBoolean(key == 1);
+      break;
+    case BYTE:
+      keyBinarySortableSerializeWrite.writeByte((byte) key);
+      break;
+    case SHORT:
+      keyBinarySortableSerializeWrite.writeShort((short) key);
+      break;
+    case INT:
+      keyBinarySortableSerializeWrite.writeInt((int) key);
+      break;
+    case LONG:
+      keyBinarySortableSerializeWrite.writeLong(key);
+      break;
+    default:
+      throw new RuntimeException("Unexpected hash table key type " + hashTableKeyType.name());
+    }
+
+    // byte[] bytes = Arrays.copyOf(output.getData(), output.getLength());
+    // LOG.info("VectorMapJoinOptimizedLongCommon serialize key " + key + " hashTableKeyType " + hashTableKeyType.name() + " hex " + Hex.encodeHexString(bytes));
+
+    serializedBytes.bytes = output.getData();
+    serializedBytes.offset = 0;
+    serializedBytes.length = output.getLength();
+
+    return serializedBytes;
+  }
+
+  public VectorMapJoinOptimizedLongCommon(
+        boolean minMaxEnabled, boolean isOuterJoin, HashTableKeyType hashTableKeyType) {
+    this.isOuterJoin = isOuterJoin;
+    // useMinMax = minMaxEnabled;
+    min = Long.MAX_VALUE;
+    max = Long.MIN_VALUE;
+    this.hashTableKeyType = hashTableKeyType;
+    // PrimitiveTypeInfo[] primitiveTypeInfos = { TypeInfoFactory.longTypeInfo };
+    // keyBinarySortableDeserializeRead = new BinarySortableDeserializeRead(primitiveTypeInfos);
+    keyBinarySortableSerializeWrite = new BinarySortableSerializeWrite(1);
+    output = new Output();
+    keyBinarySortableSerializeWrite.set(output);
+    serializedBytes = new SerializedBytes();
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashMap.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashMap.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashMap.java
new file mode 100644
index 0000000..403d265
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashMap.java
@@ -0,0 +1,82 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import java.io.IOException;
+
+import org.apache.hadoop.hive.ql.exec.JoinUtil.JoinResult;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer.ReusableGetAdaptor;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinHashMapResult;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinLongHashMap;
+import org.apache.hadoop.hive.ql.plan.VectorMapJoinDesc.HashTableKeyType;
+
+/*
+ * An single long value hash map based on the BytesBytesMultiHashMap.
+ *
+ * We serialize the long key into BinarySortable format into an output buffer accepted by
+ * BytesBytesMultiHashMap.
+ */
+public class VectorMapJoinOptimizedLongHashMap
+              extends VectorMapJoinOptimizedHashMap
+              implements VectorMapJoinLongHashMap {
+
+  private VectorMapJoinOptimizedLongCommon longCommon;
+
+  @Override
+  public boolean useMinMax() {
+    return longCommon.useMinMax();
+  }
+
+  @Override
+  public long min() {
+    return longCommon.min();
+  }
+
+  @Override
+  public long max() {
+    return longCommon.max();
+  }
+
+  /*
+  @Override
+  public void putRow(BytesWritable currentKey, BytesWritable currentValue)
+      throws SerDeException, HiveException, IOException {
+
+    longCommon.adaptPutRow((VectorMapJoinOptimizedHashTable) this, currentKey, currentValue);
+  }
+  */
+
+  @Override
+  public JoinResult lookup(long key,
+      VectorMapJoinHashMapResult hashMapResult) throws IOException {
+
+    SerializedBytes serializedBytes = longCommon.serialize(key);
+
+    return super.lookup(serializedBytes.bytes, serializedBytes.offset, serializedBytes.length,
+            hashMapResult);
+  }
+
+  public VectorMapJoinOptimizedLongHashMap(
+        boolean minMaxEnabled, boolean isOuterJoin, HashTableKeyType hashTableKeyType,
+        MapJoinTableContainer originalTableContainer, ReusableGetAdaptor hashMapRowGetter) {
+    super(originalTableContainer, hashMapRowGetter);
+    longCommon =  new VectorMapJoinOptimizedLongCommon(minMaxEnabled, isOuterJoin, hashTableKeyType);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashMultiSet.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashMultiSet.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashMultiSet.java
new file mode 100644
index 0000000..5fb8c3a
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashMultiSet.java
@@ -0,0 +1,83 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import java.io.IOException;
+
+import org.apache.hadoop.hive.ql.exec.JoinUtil.JoinResult;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer.ReusableGetAdaptor;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinHashMultiSetResult;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinLongHashMultiSet;
+import org.apache.hadoop.hive.ql.plan.VectorMapJoinDesc.HashTableKeyType;
+
+/*
+ * An single long value hash map based on the BytesBytesMultiHashMultiSet.
+ *
+ * We serialize the long key into BinarySortable format into an output buffer accepted by
+ * BytesBytesMultiHashMultiSet.
+ */
+public class VectorMapJoinOptimizedLongHashMultiSet
+              extends VectorMapJoinOptimizedHashMultiSet
+              implements VectorMapJoinLongHashMultiSet  {
+
+  private VectorMapJoinOptimizedLongCommon longCommon;
+
+  @Override
+  public boolean useMinMax() {
+    return longCommon.useMinMax();
+  }
+
+  @Override
+  public long min() {
+    return longCommon.min();
+  }
+
+  @Override
+  public long max() {
+    return longCommon.max();
+  }
+
+  /*
+  @Override
+  public void putRow(BytesWritable currentKey, BytesWritable currentValue)
+      throws SerDeException, HiveException, IOException {
+
+    longCommon.adaptPutRow((VectorMapJoinOptimizedHashTable) this, currentKey, currentValue);
+  }
+  */
+
+  @Override
+  public JoinResult contains(long key,
+      VectorMapJoinHashMultiSetResult hashMultiSetResult) throws IOException {
+
+    SerializedBytes serializedBytes = longCommon.serialize(key);
+
+    return super.contains(serializedBytes.bytes, serializedBytes.offset, serializedBytes.length,
+        hashMultiSetResult);
+
+  }
+
+  public VectorMapJoinOptimizedLongHashMultiSet(
+        boolean minMaxEnabled, boolean isOuterJoin, HashTableKeyType hashTableKeyType,
+        MapJoinTableContainer originalTableContainer, ReusableGetAdaptor hashMapRowGetter) {
+    super(originalTableContainer, hashMapRowGetter);
+    longCommon =  new VectorMapJoinOptimizedLongCommon(minMaxEnabled, isOuterJoin, hashTableKeyType);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashSet.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashSet.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashSet.java
new file mode 100644
index 0000000..c41505a
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedLongHashSet.java
@@ -0,0 +1,83 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import java.io.IOException;
+
+import org.apache.hadoop.hive.ql.exec.JoinUtil.JoinResult;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer.ReusableGetAdaptor;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinHashSetResult;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinLongHashSet;
+import org.apache.hadoop.hive.ql.plan.VectorMapJoinDesc.HashTableKeyType;
+
+/*
+ * An single long value hash map based on the BytesBytesMultiHashSet.
+ *
+ * We serialize the long key into BinarySortable format into an output buffer accepted by
+ * BytesBytesMultiHashSet.
+ */
+public class VectorMapJoinOptimizedLongHashSet
+              extends VectorMapJoinOptimizedHashSet
+              implements VectorMapJoinLongHashSet  {
+
+  private VectorMapJoinOptimizedLongCommon longCommon;
+
+  @Override
+  public boolean useMinMax() {
+    return longCommon.useMinMax();
+  }
+
+  @Override
+  public long min() {
+    return longCommon.min();
+  }
+
+  @Override
+  public long max() {
+    return longCommon.max();
+  }
+
+  /*
+  @Override
+  public void putRow(BytesWritable currentKey, BytesWritable currentValue)
+      throws SerDeException, HiveException, IOException {
+
+    longCommon.adaptPutRow((VectorMapJoinOptimizedHashTable) this, currentKey, currentValue);
+  }
+  */
+
+  @Override
+  public JoinResult contains(long key,
+      VectorMapJoinHashSetResult hashSetResult) throws IOException {
+
+    SerializedBytes serializedBytes = longCommon.serialize(key);
+
+    return super.contains(serializedBytes.bytes, serializedBytes.offset, serializedBytes.length,
+        hashSetResult);
+
+  }
+
+  public VectorMapJoinOptimizedLongHashSet(
+        boolean minMaxEnabled, boolean isOuterJoin, HashTableKeyType hashTableKeyType,
+        MapJoinTableContainer originalTableContainer, ReusableGetAdaptor hashMapRowGetter) {
+    super(originalTableContainer, hashMapRowGetter);
+    longCommon =  new VectorMapJoinOptimizedLongCommon(minMaxEnabled, isOuterJoin, hashTableKeyType);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashMap.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashMap.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashMap.java
new file mode 100644
index 0000000..4f3e20e
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashMap.java
@@ -0,0 +1,36 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer.ReusableGetAdaptor;
+
+/*
+ * An multi-key hash map based on the BytesBytesMultiHashMap.
+ */
+public class VectorMapJoinOptimizedMultiKeyHashMap
+             extends VectorMapJoinOptimizedHashMap  {
+
+  // UNDONE: How to look for all NULLs in a multi-key?????  Let nulls through for now.
+
+  public VectorMapJoinOptimizedMultiKeyHashMap(boolean isOuterJoin,
+      MapJoinTableContainer originalTableContainer, ReusableGetAdaptor hashMapRowGetter) {
+    super(originalTableContainer, hashMapRowGetter);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashMultiSet.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashMultiSet.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashMultiSet.java
new file mode 100644
index 0000000..b95a2dd
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashMultiSet.java
@@ -0,0 +1,36 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer.ReusableGetAdaptor;
+
+/*
+ * An multi-key hash map based on the BytesBytesMultiHashMultiSet.
+ */
+public class VectorMapJoinOptimizedMultiKeyHashMultiSet
+              extends VectorMapJoinOptimizedHashMultiSet {
+
+  // UNDONE: How to look for all NULLs in a multi-key?????  Let nulls through for now.
+
+  public VectorMapJoinOptimizedMultiKeyHashMultiSet(boolean isOuterJoin,
+      MapJoinTableContainer originalTableContainer, ReusableGetAdaptor hashMapRowGetter) {
+    super(originalTableContainer, hashMapRowGetter);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashSet.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashSet.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashSet.java
new file mode 100644
index 0000000..35ecc2a
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedMultiKeyHashSet.java
@@ -0,0 +1,36 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer.ReusableGetAdaptor;
+
+/*
+ * An multi-key hash map based on the BytesBytesMultiHashSet.
+ */
+public class VectorMapJoinOptimizedMultiKeyHashSet
+              extends VectorMapJoinOptimizedHashSet {
+
+  // UNDONE: How to look for all NULLs in a multi-key?????  Let nulls through for now.
+
+  public VectorMapJoinOptimizedMultiKeyHashSet(boolean isOuterJoin,
+      MapJoinTableContainer originalTableContainer, ReusableGetAdaptor hashMapRowGetter) {
+    super(originalTableContainer, hashMapRowGetter);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringCommon.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringCommon.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringCommon.java
new file mode 100644
index 0000000..39c2d49
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringCommon.java
@@ -0,0 +1,98 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import java.io.IOException;
+
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.optimized.VectorMapJoinOptimizedHashTable.SerializedBytes;
+import org.apache.hadoop.hive.serde2.ByteStream.Output;
+import org.apache.hadoop.hive.serde2.binarysortable.fast.BinarySortableSerializeWrite;
+
+/*
+ * An single byte array value hash map based on the BytesBytesMultiHashMap.
+ *
+ * Since BytesBytesMultiHashMap does not interpret the key as BinarySortable we optimize
+ * this case and just reference the byte array key directly for the lookup instead of serializing
+ * the byte array into BinarySortable. We rely on it just doing byte array equality comparisons.
+ */
+public class VectorMapJoinOptimizedStringCommon {
+
+  // private boolean isOuterJoin;
+
+  // private BinarySortableDeserializeRead keyBinarySortableDeserializeRead;
+
+  // private ReadStringResults readStringResults;
+
+  private BinarySortableSerializeWrite keyBinarySortableSerializeWrite;
+
+  private transient Output output;
+
+  private transient SerializedBytes serializedBytes;
+
+  /*
+  private BytesWritable bytesWritable;
+
+  public void adaptPutRow(VectorMapJoinOptimizedHashTable hashTable,
+      BytesWritable currentKey, BytesWritable currentValue)
+      throws SerDeException, HiveException, IOException {
+
+    byte[] keyBytes = currentKey.getBytes();
+    int keyLength = currentKey.getLength();
+    keyBinarySortableDeserializeRead.set(keyBytes, 0, keyLength);
+    if (keyBinarySortableDeserializeRead.readCheckNull()) {
+      if (isOuterJoin) {
+        return;
+      } else {
+        // For inner join, we expect all NULL values to have been filtered out before now.
+        throw new HiveException("Unexpected NULL");
+      }
+    }
+    keyBinarySortableDeserializeRead.readString(readStringResults);
+
+    bytesWritable.set(readStringResults.bytes, readStringResults.start, readStringResults.length);
+
+    hashTable.putRowInternal(bytesWritable, currentValue);
+  }
+  */
+
+  public SerializedBytes serialize(byte[] keyBytes, int keyStart, int keyLength) throws IOException {
+
+    keyBinarySortableSerializeWrite.reset();
+    keyBinarySortableSerializeWrite.writeString(keyBytes, keyStart, keyLength);
+
+    serializedBytes.bytes = output.getData();
+    serializedBytes.offset = 0;
+    serializedBytes.length = output.getLength();
+
+    return serializedBytes;
+
+  }
+
+  public VectorMapJoinOptimizedStringCommon(boolean isOuterJoin) {
+    // this.isOuterJoin = isOuterJoin;
+    // PrimitiveTypeInfo[] primitiveTypeInfos = { TypeInfoFactory.stringTypeInfo };
+    // keyBinarySortableDeserializeRead = new BinarySortableDeserializeRead(primitiveTypeInfos);
+    // readStringResults = keyBinarySortableDeserializeRead.createReadStringResults();
+    // bytesWritable = new BytesWritable();
+    keyBinarySortableSerializeWrite = new BinarySortableSerializeWrite(1);
+    output = new Output();
+    keyBinarySortableSerializeWrite.set(output);
+    serializedBytes = new SerializedBytes();
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashMap.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashMap.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashMap.java
new file mode 100644
index 0000000..220c05e
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashMap.java
@@ -0,0 +1,63 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import java.io.IOException;
+
+import org.apache.hadoop.hive.ql.exec.JoinUtil.JoinResult;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer.ReusableGetAdaptor;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinBytesHashMap;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinHashMapResult;
+
+/*
+ * An multi-key hash map based on the BytesBytesMultiHashMap.
+ */
+public class VectorMapJoinOptimizedStringHashMap
+             extends VectorMapJoinOptimizedHashMap
+             implements VectorMapJoinBytesHashMap {
+
+  private VectorMapJoinOptimizedStringCommon stringCommon;
+
+  /*
+  @Override
+  public void putRow(BytesWritable currentKey, BytesWritable currentValue)
+      throws SerDeException, HiveException, IOException {
+
+    stringCommon.adaptPutRow((VectorMapJoinOptimizedHashTable) this, currentKey, currentValue);
+  }
+  */
+
+  @Override
+  public JoinResult lookup(byte[] keyBytes, int keyStart, int keyLength,
+      VectorMapJoinHashMapResult hashMapResult) throws IOException {
+
+    SerializedBytes serializedBytes = stringCommon.serialize(keyBytes, keyStart, keyLength);
+
+    return super.lookup(serializedBytes.bytes, serializedBytes.offset, serializedBytes.length,
+            hashMapResult);
+
+  }
+
+  public VectorMapJoinOptimizedStringHashMap(boolean isOuterJoin,
+      MapJoinTableContainer originalTableContainer, ReusableGetAdaptor hashMapRowGetter) {
+    super(originalTableContainer, hashMapRowGetter);
+    stringCommon =  new VectorMapJoinOptimizedStringCommon(isOuterJoin);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashMultiSet.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashMultiSet.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashMultiSet.java
new file mode 100644
index 0000000..b6c6958
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashMultiSet.java
@@ -0,0 +1,64 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import java.io.IOException;
+
+import org.apache.hadoop.hive.ql.exec.JoinUtil.JoinResult;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer.ReusableGetAdaptor;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinBytesHashMultiSet;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinHashMultiSetResult;
+
+/*
+ * An multi-key hash map based on the BytesBytesMultiHashMultiSet.
+ */
+public class VectorMapJoinOptimizedStringHashMultiSet
+              extends VectorMapJoinOptimizedHashMultiSet
+              implements VectorMapJoinBytesHashMultiSet {
+
+  private VectorMapJoinOptimizedStringCommon stringCommon;
+
+  /*
+  @Override
+  public void putRow(BytesWritable currentKey, BytesWritable currentValue)
+      throws SerDeException, HiveException, IOException {
+
+    stringCommon.adaptPutRow((VectorMapJoinOptimizedHashTable) this, currentKey, currentValue);
+  }
+  */
+
+  @Override
+  public JoinResult contains(byte[] keyBytes, int keyStart, int keyLength,
+      VectorMapJoinHashMultiSetResult hashMultiSetResult) throws IOException {
+
+    SerializedBytes serializedBytes = stringCommon.serialize(keyBytes, keyStart, keyLength);
+
+    return super.contains(serializedBytes.bytes, serializedBytes.offset, serializedBytes.length,
+        hashMultiSetResult);
+
+
+  }
+
+  public VectorMapJoinOptimizedStringHashMultiSet(boolean isOuterJoin,
+      MapJoinTableContainer originalTableContainer, ReusableGetAdaptor hashMapRowGetter) {
+    super(originalTableContainer, hashMapRowGetter);
+    stringCommon =  new VectorMapJoinOptimizedStringCommon(isOuterJoin);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashSet.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashSet.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashSet.java
new file mode 100644
index 0000000..f921b9c
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/optimized/VectorMapJoinOptimizedStringHashSet.java
@@ -0,0 +1,63 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.optimized;
+
+import java.io.IOException;
+
+import org.apache.hadoop.hive.ql.exec.JoinUtil.JoinResult;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinTableContainer.ReusableGetAdaptor;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinBytesHashSet;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinHashSetResult;
+
+/*
+ * An multi-key hash map based on the BytesBytesMultiHashSet.
+ */
+public class VectorMapJoinOptimizedStringHashSet
+              extends VectorMapJoinOptimizedHashSet
+              implements VectorMapJoinBytesHashSet {
+
+  private VectorMapJoinOptimizedStringCommon stringCommon;
+
+  /*
+  @Override
+  public void putRow(BytesWritable currentKey, BytesWritable currentValue)
+      throws SerDeException, HiveException, IOException {
+
+    stringCommon.adaptPutRow((VectorMapJoinOptimizedHashTable) this, currentKey, currentValue);
+  }
+  */
+
+  @Override
+  public JoinResult contains(byte[] keyBytes, int keyStart, int keyLength,
+      VectorMapJoinHashSetResult hashSetResult) throws IOException {
+
+    SerializedBytes serializedBytes = stringCommon.serialize(keyBytes, keyStart, keyLength);
+
+    return super.contains(serializedBytes.bytes, serializedBytes.offset, serializedBytes.length,
+        hashSetResult);
+
+  }
+
+  public VectorMapJoinOptimizedStringHashSet(boolean isOuterJoin,
+      MapJoinTableContainer originalTableContainer, ReusableGetAdaptor hashMapRowGetter) {
+    super(originalTableContainer, hashMapRowGetter);
+    stringCommon =  new VectorMapJoinOptimizedStringCommon(isOuterJoin);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/Vectorizer.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/Vectorizer.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/Vectorizer.java
index 319aacb..615fd8a 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/Vectorizer.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/Vectorizer.java
@@ -21,7 +21,6 @@ package org.apache.hadoop.hive.ql.optimizer.physical;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
@@ -30,7 +29,6 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 import java.util.Stack;
-import java.util.TreeMap;
 import java.util.regex.Pattern;
 
 import org.apache.commons.logging.Log;
@@ -39,10 +37,23 @@ import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
 import org.apache.hadoop.hive.ql.exec.*;
 import org.apache.hadoop.hive.ql.exec.mr.MapRedTask;
+import org.apache.hadoop.hive.ql.exec.persistence.MapJoinKey;
 import org.apache.hadoop.hive.ql.exec.spark.SparkTask;
 import org.apache.hadoop.hive.ql.exec.tez.TezTask;
 import org.apache.hadoop.hive.ql.exec.vector.VectorExpressionDescriptor;
 import org.apache.hadoop.hive.ql.exec.vector.VectorGroupByOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinInnerBigOnlyLongOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinInnerBigOnlyMultiKeyOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinInnerBigOnlyStringOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinInnerLongOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinInnerMultiKeyOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinInnerStringOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinLeftSemiLongOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinLeftSemiMultiKeyOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinLeftSemiStringOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinOuterLongOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinOuterMultiKeyOperator;
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.VectorMapJoinOuterStringOperator;
 import org.apache.hadoop.hive.ql.exec.vector.VectorizationContext;
 import org.apache.hadoop.hive.ql.exec.vector.VectorizationContextRegion;
 import org.apache.hadoop.hive.ql.exec.vector.VectorizedInputFormatInterface;
@@ -68,6 +79,7 @@ import org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc;
 import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
 import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc;
 import org.apache.hadoop.hive.ql.plan.GroupByDesc;
+import org.apache.hadoop.hive.ql.plan.JoinDesc;
 import org.apache.hadoop.hive.ql.plan.MapJoinDesc;
 import org.apache.hadoop.hive.ql.plan.MapWork;
 import org.apache.hadoop.hive.ql.plan.OperatorDesc;
@@ -78,6 +90,10 @@ import org.apache.hadoop.hive.ql.plan.SparkWork;
 import org.apache.hadoop.hive.ql.plan.TableScanDesc;
 import org.apache.hadoop.hive.ql.plan.TezWork;
 import org.apache.hadoop.hive.ql.plan.VectorGroupByDesc;
+import org.apache.hadoop.hive.ql.plan.VectorMapJoinDesc;
+import org.apache.hadoop.hive.ql.plan.VectorMapJoinDesc.HashTableImplementationType;
+import org.apache.hadoop.hive.ql.plan.VectorMapJoinDesc.HashTableKeyType;
+import org.apache.hadoop.hive.ql.plan.VectorMapJoinDesc.HashTableKind;
 import org.apache.hadoop.hive.ql.plan.api.OperatorType;
 import org.apache.hadoop.hive.ql.udf.UDFAcos;
 import org.apache.hadoop.hive.ql.udf.UDFAsin;
@@ -313,7 +329,7 @@ public class Vectorizer implements PhysicalPlanResolver {
             // We are only vectorizing Reduce under Tez.
             if (HiveConf.getBoolVar(hiveConf,
                         HiveConf.ConfVars.HIVE_VECTORIZATION_REDUCE_ENABLED)) {
-              convertReduceWork((ReduceWork) w);
+              convertReduceWork((ReduceWork) w, true);
             }
           }
         }
@@ -325,7 +341,7 @@ public class Vectorizer implements PhysicalPlanResolver {
           } else if (baseWork instanceof ReduceWork
               && HiveConf.getBoolVar(hiveConf,
                   HiveConf.ConfVars.HIVE_VECTORIZATION_REDUCE_ENABLED)) {
-            convertReduceWork((ReduceWork) baseWork);
+            convertReduceWork((ReduceWork) baseWork, false);
           }
         }
       }
@@ -335,7 +351,7 @@ public class Vectorizer implements PhysicalPlanResolver {
     private void convertMapWork(MapWork mapWork, boolean isTez) throws SemanticException {
       boolean ret = validateMapWork(mapWork, isTez);
       if (ret) {
-        vectorizeMapWork(mapWork);
+        vectorizeMapWork(mapWork, isTez);
       }
     }
 
@@ -391,11 +407,11 @@ public class Vectorizer implements PhysicalPlanResolver {
       return true;
     }
 
-    private void vectorizeMapWork(MapWork mapWork) throws SemanticException {
+    private void vectorizeMapWork(MapWork mapWork, boolean isTez) throws SemanticException {
       LOG.info("Vectorizing MapWork...");
       mapWork.setVectorMode(true);
       Map<Rule, NodeProcessor> opRules = new LinkedHashMap<Rule, NodeProcessor>();
-      MapWorkVectorizationNodeProcessor vnp = new MapWorkVectorizationNodeProcessor(mapWork);
+      MapWorkVectorizationNodeProcessor vnp = new MapWorkVectorizationNodeProcessor(mapWork, isTez);
       addMapWorkRules(opRules, vnp);
       Dispatcher disp = new DefaultRuleDispatcher(vnp, opRules, null);
       GraphWalker ogw = new PreOrderWalker(disp);
@@ -416,10 +432,10 @@ public class Vectorizer implements PhysicalPlanResolver {
       return;
     }
 
-    private void convertReduceWork(ReduceWork reduceWork) throws SemanticException {
+    private void convertReduceWork(ReduceWork reduceWork, boolean isTez) throws SemanticException {
       boolean ret = validateReduceWork(reduceWork);
       if (ret) {
-        vectorizeReduceWork(reduceWork);
+        vectorizeReduceWork(reduceWork, isTez);
       }
     }
 
@@ -497,7 +513,7 @@ public class Vectorizer implements PhysicalPlanResolver {
       return true;
     }
 
-    private void vectorizeReduceWork(ReduceWork reduceWork) throws SemanticException {
+    private void vectorizeReduceWork(ReduceWork reduceWork, boolean isTez) throws SemanticException {
       LOG.info("Vectorizing ReduceWork...");
       reduceWork.setVectorMode(true);
 
@@ -506,7 +522,7 @@ public class Vectorizer implements PhysicalPlanResolver {
       // VectorizationContext...  Do we use PreOrderWalker instead of DefaultGraphWalker.
       Map<Rule, NodeProcessor> opRules = new LinkedHashMap<Rule, NodeProcessor>();
       ReduceWorkVectorizationNodeProcessor vnp =
-              new ReduceWorkVectorizationNodeProcessor(reduceColumnNames, reduceTypeInfos);
+              new ReduceWorkVectorizationNodeProcessor(reduceColumnNames, reduceTypeInfos, isTez);
       addReduceWorkRules(opRules, vnp);
       Dispatcher disp = new DefaultRuleDispatcher(vnp, opRules, null);
       GraphWalker ogw = new PreOrderWalker(disp);
@@ -645,11 +661,11 @@ public class Vectorizer implements PhysicalPlanResolver {
     }
 
     public Operator<? extends OperatorDesc> doVectorize(Operator<? extends OperatorDesc> op,
-            VectorizationContext vContext) throws SemanticException {
+            VectorizationContext vContext, boolean isTez) throws SemanticException {
       Operator<? extends OperatorDesc> vectorOp = op;
       try {
         if (!opsDone.contains(op)) {
-          vectorOp = vectorizeOperator(op, vContext);
+          vectorOp = vectorizeOperator(op, vContext, isTez);
           opsDone.add(op);
           if (vectorOp != op) {
             opToVectorOpMap.put(op, vectorOp);
@@ -672,10 +688,12 @@ public class Vectorizer implements PhysicalPlanResolver {
   class MapWorkVectorizationNodeProcessor extends VectorizationNodeProcessor {
 
     private final MapWork mWork;
+    private final boolean isTez;
 
-    public MapWorkVectorizationNodeProcessor(MapWork mWork) {
+    public MapWorkVectorizationNodeProcessor(MapWork mWork, boolean isTez) {
       super();
       this.mWork = mWork;
+      this.isTez = isTez;
     }
 
     @Override
@@ -714,7 +732,7 @@ public class Vectorizer implements PhysicalPlanResolver {
         return null;
       }
 
-      Operator<? extends OperatorDesc> vectorOp = doVectorize(op, vContext);
+      Operator<? extends OperatorDesc> vectorOp = doVectorize(op, vContext, isTez);
 
       if (LOG.isDebugEnabled()) {
         if (vectorOp instanceof VectorizationContextRegion) {
@@ -733,6 +751,8 @@ public class Vectorizer implements PhysicalPlanResolver {
     private final List<String> reduceColumnNames;
     private final List<TypeInfo> reduceTypeInfos;
 
+    private boolean isTez;
+
     private Operator<? extends OperatorDesc> rootVectorOp;
 
     public Operator<? extends OperatorDesc> getRootVectorOp() {
@@ -740,11 +760,12 @@ public class Vectorizer implements PhysicalPlanResolver {
     }
 
     public ReduceWorkVectorizationNodeProcessor(List<String> reduceColumnNames,
-            List<TypeInfo> reduceTypeInfos) {
+            List<TypeInfo> reduceTypeInfos, boolean isTez) {
       super();
       this.reduceColumnNames =  reduceColumnNames;
       this.reduceTypeInfos = reduceTypeInfos;
       rootVectorOp = null;
+      this.isTez = isTez;
     }
 
     @Override
@@ -795,7 +816,7 @@ public class Vectorizer implements PhysicalPlanResolver {
         return null;
       }
 
-      Operator<? extends OperatorDesc> vectorOp = doVectorize(op, vContext);
+      Operator<? extends OperatorDesc> vectorOp = doVectorize(op, vContext, isTez);
 
       if (LOG.isDebugEnabled()) {
         if (vectorOp instanceof VectorizationContextRegion) {
@@ -1304,12 +1325,278 @@ public class Vectorizer implements PhysicalPlanResolver {
     }
   }
 
+  private boolean isBigTableOnlyResults(MapJoinDesc desc) {
+    Byte[] order = desc.getTagOrder();
+    byte posBigTable = (byte) desc.getPosBigTable();
+    Byte posSingleVectorMapJoinSmallTable = (order[0] == posBigTable ? order[1] : order[0]);
+
+    int[] smallTableIndices;
+    int smallTableIndicesSize;
+    List<ExprNodeDesc> smallTableExprs = desc.getExprs().get(posSingleVectorMapJoinSmallTable);
+    if (desc.getValueIndices() != null && desc.getValueIndices().get(posSingleVectorMapJoinSmallTable) != null) {
+      smallTableIndices = desc.getValueIndices().get(posSingleVectorMapJoinSmallTable);
+      LOG.info("Vectorizer isBigTableOnlyResults smallTableIndices " + Arrays.toString(smallTableIndices));
+      smallTableIndicesSize = smallTableIndices.length;
+    } else {
+      smallTableIndices = null;
+      LOG.info("Vectorizer isBigTableOnlyResults smallTableIndices EMPTY");
+      smallTableIndicesSize = 0;
+    }
+
+    List<Integer> smallTableRetainList = desc.getRetainList().get(posSingleVectorMapJoinSmallTable);
+    LOG.info("Vectorizer isBigTableOnlyResults smallTableRetainList " + smallTableRetainList);
+    int smallTableRetainSize = smallTableRetainList.size();
+
+    if (smallTableIndicesSize > 0) {
+      // Small table indices has priority over retain.
+      for (int i = 0; i < smallTableIndicesSize; i++) {
+        if (smallTableIndices[i] < 0) {
+          // Negative numbers indicate a column to be (deserialize) read from the small table's
+          // LazyBinary value row.
+          LOG.info("Vectorizer isBigTableOnlyResults smallTableIndices[i] < 0 returning false");
+          return false;
+        }
+      }
+    } else if (smallTableRetainSize > 0) {
+      LOG.info("Vectorizer isBigTableOnlyResults smallTableRetainSize > 0 returning false");
+      return false;
+    }
+
+    LOG.info("Vectorizer isBigTableOnlyResults returning true");
+    return true;
+  }
+
+  Operator<? extends OperatorDesc> specializeMapJoinOperator(Operator<? extends OperatorDesc> op,
+        VectorizationContext vContext, MapJoinDesc desc) throws HiveException {
+    Operator<? extends OperatorDesc> vectorOp = null;
+    Class<? extends Operator<?>> opClass = null;
+
+    boolean isOuterJoin = !desc.getNoOuterJoin();
+
+    VectorMapJoinDesc.HashTableImplementationType hashTableImplementationType = HashTableImplementationType.NONE;
+    VectorMapJoinDesc.HashTableKind hashTableKind = HashTableKind.NONE;
+    VectorMapJoinDesc.HashTableKeyType hashTableKeyType = HashTableKeyType.NONE;
+
+    if (HiveConf.getBoolVar(hiveConf,
+              HiveConf.ConfVars.HIVE_VECTORIZATION_MAPJOIN_NATIVE_FAST_HASHTABLE_ENABLED)) {
+      hashTableImplementationType = HashTableImplementationType.FAST;
+    } else {
+      // Restrict to using BytesBytesMultiHashMap via MapJoinBytesTableContainer or
+      // HybridHashTableContainer.
+      hashTableImplementationType = HashTableImplementationType.OPTIMIZED;
+    }
+
+    int joinType = desc.getConds()[0].getType();
+
+    boolean isInnerBigOnly = false;
+    if (joinType == JoinDesc.INNER_JOIN && isBigTableOnlyResults(desc)) {
+      isInnerBigOnly = true;
+    }
+
+    // By default, we can always use the multi-key class.
+    hashTableKeyType = HashTableKeyType.MULTI_KEY;
+
+    if (!HiveConf.getBoolVar(hiveConf,
+        HiveConf.ConfVars.HIVE_VECTORIZATION_MAPJOIN_NATIVE_MULTIKEY_ONLY_ENABLED)) {
+
+      // Look for single column optimization.
+      byte posBigTable = (byte) desc.getPosBigTable();
+      Map<Byte, List<ExprNodeDesc>> keyExprs = desc.getKeys();
+      List<ExprNodeDesc> bigTableKeyExprs = keyExprs.get(posBigTable);
+      if (bigTableKeyExprs.size() == 1) {
+        String typeName = bigTableKeyExprs.get(0).getTypeString();
+        LOG.info("Vectorizer vectorizeOperator map join typeName " + typeName);
+        if (typeName.equals("boolean")) {
+          hashTableKeyType = HashTableKeyType.BOOLEAN;
+        } else if (typeName.equals("tinyint")) {
+          hashTableKeyType = HashTableKeyType.BYTE;
+        } else if (typeName.equals("smallint")) {
+          hashTableKeyType = HashTableKeyType.SHORT;
+        } else if (typeName.equals("int")) {
+          hashTableKeyType = HashTableKeyType.INT;
+        } else if (typeName.equals("bigint") || typeName.equals("long")) {
+          hashTableKeyType = HashTableKeyType.LONG;
+        } else if (VectorizationContext.isStringFamily(typeName)) {
+          hashTableKeyType = HashTableKeyType.STRING;
+        }
+      }
+    }
+
+    switch (joinType) {
+    case JoinDesc.INNER_JOIN:
+      if (!isInnerBigOnly) {
+        hashTableKind = HashTableKind.HASH_MAP;
+      } else {
+        hashTableKind = HashTableKind.HASH_MULTISET;
+      }
+      break;
+    case JoinDesc.LEFT_OUTER_JOIN:
+    case JoinDesc.RIGHT_OUTER_JOIN:
+      hashTableKind = HashTableKind.HASH_MAP;
+      break;
+    case JoinDesc.LEFT_SEMI_JOIN:
+      hashTableKind = HashTableKind.HASH_SET;
+      break;
+    default:
+      throw new HiveException("Unknown join type " + joinType);
+    }
+
+    LOG.info("Vectorizer vectorizeOperator map join hashTableKind " + hashTableKind.name() + " hashTableKeyType " + hashTableKeyType.name());
+
+    switch (hashTableKeyType) {
+    case BOOLEAN:
+    case BYTE:
+    case SHORT:
+    case INT:
+    case LONG:
+      switch (joinType) {
+      case JoinDesc.INNER_JOIN:
+        if (!isInnerBigOnly) {
+          opClass = VectorMapJoinInnerLongOperator.class;
+        } else {
+          opClass = VectorMapJoinInnerBigOnlyLongOperator.class;
+        }
+        break;
+      case JoinDesc.LEFT_OUTER_JOIN:
+      case JoinDesc.RIGHT_OUTER_JOIN:
+        opClass = VectorMapJoinOuterLongOperator.class;
+        break;
+      case JoinDesc.LEFT_SEMI_JOIN:
+        opClass = VectorMapJoinLeftSemiLongOperator.class;
+        break;
+      default:
+        throw new HiveException("Unknown join type " + joinType);
+      }
+      break;
+    case STRING:
+      switch (joinType) {
+      case JoinDesc.INNER_JOIN:
+        if (!isInnerBigOnly) {
+          opClass = VectorMapJoinInnerStringOperator.class;
+        } else {
+          opClass = VectorMapJoinInnerBigOnlyStringOperator.class;
+        }
+        break;
+      case JoinDesc.LEFT_OUTER_JOIN:
+      case JoinDesc.RIGHT_OUTER_JOIN:
+        opClass = VectorMapJoinOuterStringOperator.class;
+        break;
+      case JoinDesc.LEFT_SEMI_JOIN:
+        opClass = VectorMapJoinLeftSemiStringOperator.class;
+        break;
+      default:
+        throw new HiveException("Unknown join type " + joinType);
+      }
+      break;
+    case MULTI_KEY:
+      switch (joinType) {
+      case JoinDesc.INNER_JOIN:
+        if (!isInnerBigOnly) {
+          opClass = VectorMapJoinInnerMultiKeyOperator.class;
+        } else {
+          opClass = VectorMapJoinInnerBigOnlyMultiKeyOperator.class;
+        }
+        break;
+      case JoinDesc.LEFT_OUTER_JOIN:
+      case JoinDesc.RIGHT_OUTER_JOIN:
+        opClass = VectorMapJoinOuterMultiKeyOperator.class;
+        break;
+      case JoinDesc.LEFT_SEMI_JOIN:
+        opClass = VectorMapJoinLeftSemiMultiKeyOperator.class;
+        break;
+      default:
+        throw new HiveException("Unknown join type " + joinType);
+      }
+      break;
+    }
+
+    vectorOp = OperatorFactory.getVectorOperator(opClass, op.getConf(), vContext);
+    LOG.info("Vectorizer vectorizeOperator map join class " + vectorOp.getClass().getSimpleName());
+
+    boolean minMaxEnabled = HiveConf.getBoolVar(hiveConf,
+        HiveConf.ConfVars.HIVE_VECTORIZATION_MAPJOIN_NATIVE_MINMAX_ENABLED);
+
+    VectorMapJoinDesc vectorDesc = desc.getVectorDesc();
+    vectorDesc.setHashTableImplementationType(hashTableImplementationType);
+    vectorDesc.setHashTableKind(hashTableKind);
+    vectorDesc.setHashTableKeyType(hashTableKeyType);
+    vectorDesc.setMinMaxEnabled(minMaxEnabled);
+    return vectorOp;
+  }
+
+  private boolean canSpecializeMapJoin(Operator<? extends OperatorDesc> op, MapJoinDesc desc,
+      boolean isTez) {
+
+    boolean specialize = false;
+
+    if (op instanceof MapJoinOperator &&
+        HiveConf.getBoolVar(hiveConf,
+            HiveConf.ConfVars.HIVE_VECTORIZATION_MAPJOIN_NATIVE_ENABLED)) {
+
+      // Currently, only under Tez and non-N-way joins.
+      if (isTez && desc.getConds().length == 1) {
+
+        // Ok, all basic restrictions satisfied so far...
+        specialize = true;
+
+        if (!HiveConf.getBoolVar(hiveConf,
+            HiveConf.ConfVars.HIVE_VECTORIZATION_MAPJOIN_NATIVE_FAST_HASHTABLE_ENABLED)) {
+
+          // We are using the optimized hash table we have further
+          // restrictions (using optimized and key type).
+
+          if (!HiveConf.getBoolVar(hiveConf,
+              HiveConf.ConfVars.HIVEMAPJOINUSEOPTIMIZEDTABLE)) {
+            specialize = false;
+          } else {
+            byte posBigTable = (byte) desc.getPosBigTable();
+            Map<Byte, List<ExprNodeDesc>> keyExprs = desc.getKeys();
+            List<ExprNodeDesc> bigTableKeyExprs = keyExprs.get(posBigTable);
+            for (ExprNodeDesc exprNodeDesc : bigTableKeyExprs) {
+              String typeName = exprNodeDesc.getTypeString();
+              if (!MapJoinKey.isSupportedField(typeName)) {
+                specialize = false;
+                break;
+              }
+            }
+          }
+        } else {
+
+          // With the fast hash table implementation, we currently do not support
+          // Hybrid Grace Hash Join.
+
+          if (HiveConf.getBoolVar(hiveConf,
+              HiveConf.ConfVars.HIVEUSEHYBRIDGRACEHASHJOIN)) {
+            specialize = false;
+          }
+        }
+      }
+    }
+    return specialize;
+  }
+
   Operator<? extends OperatorDesc> vectorizeOperator(Operator<? extends OperatorDesc> op,
-      VectorizationContext vContext) throws HiveException {
+      VectorizationContext vContext, boolean isTez) throws HiveException {
     Operator<? extends OperatorDesc> vectorOp = null;
 
     switch (op.getType()) {
       case MAPJOIN:
+        {
+          MapJoinDesc desc = (MapJoinDesc) op.getConf();
+          boolean specialize = canSpecializeMapJoin(op, desc, isTez);
+
+          if (!specialize) {
+            vectorOp = OperatorFactory.getVectorOperator(desc, vContext);
+          } else {
+
+            // TEMPORARY Until Native Vector Map Join with Hybrid passes tests...
+            // HiveConf.setBoolVar(physicalContext.getConf(),
+            //    HiveConf.ConfVars.HIVEUSEHYBRIDGRACEHASHJOIN, false);
+
+            vectorOp = specializeMapJoinOperator(op, vContext, desc);
+          }
+        }
+        break;
       case GROUPBY:
       case FILTER:
       case SELECT:
@@ -1325,6 +1612,9 @@ public class Vectorizer implements PhysicalPlanResolver {
         break;
     }
 
+    LOG.info("vectorizeOperator " + (vectorOp == null ? "NULL" : vectorOp.getClass().getName()));
+    LOG.info("vectorizeOperator " + (vectorOp == null || vectorOp.getConf() == null ? "NULL" : vectorOp.getConf().getClass().getName()));
+
     if (vectorOp != op) {
       fixupParentChildOperators(op, vectorOp);
       ((AbstractOperatorDesc) vectorOp.getConf()).setVectorMode(true);

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/plan/BaseWork.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/plan/BaseWork.java b/ql/src/java/org/apache/hadoop/hive/ql/plan/BaseWork.java
index 4f9221e..a342738 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/plan/BaseWork.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/plan/BaseWork.java
@@ -60,6 +60,7 @@ public abstract class BaseWork extends AbstractOperatorDesc {
   private String name;
 
   // Vectorization.
+
   protected Map<String, Integer> vectorColumnNameMap;
   protected Map<Integer, String> vectorColumnTypeMap;
   protected Map<Integer, String> vectorScratchColumnTypeMap;

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/plan/MapJoinDesc.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/plan/MapJoinDesc.java b/ql/src/java/org/apache/hadoop/hive/ql/plan/MapJoinDesc.java
index c2c1b95..0192fb5 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/plan/MapJoinDesc.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/plan/MapJoinDesc.java
@@ -72,12 +72,17 @@ public class MapJoinDesc extends JoinDesc implements Serializable {
 
   private boolean isHybridHashJoin;
 
+  // Extra parameters only for vectorization.
+  private VectorMapJoinDesc vectorDesc;
+
   public MapJoinDesc() {
+    vectorDesc = new VectorMapJoinDesc();
     bigTableBucketNumMapping = new LinkedHashMap<String, Integer>();
   }
 
   public MapJoinDesc(MapJoinDesc clone) {
     super(clone);
+    vectorDesc = new VectorMapJoinDesc(clone.vectorDesc);
     this.keys = clone.keys;
     this.keyTblDesc = clone.keyTblDesc;
     this.valueTblDescs = clone.valueTblDescs;
@@ -102,6 +107,7 @@ public class MapJoinDesc extends JoinDesc implements Serializable {
       final int posBigTable, final JoinCondDesc[] conds,
       final Map<Byte, List<ExprNodeDesc>> filters, boolean noOuterJoin, String dumpFilePrefix) {
     super(values, outputColumnNames, noOuterJoin, conds, filters, null);
+    vectorDesc = new VectorMapJoinDesc();
     this.keys = keys;
     this.keyTblDesc = keyTblDesc;
     this.valueTblDescs = valueTblDescs;
@@ -112,6 +118,14 @@ public class MapJoinDesc extends JoinDesc implements Serializable {
     initRetainExprList();
   }
 
+  public void setVectorDesc(VectorMapJoinDesc vectorDesc) {
+    this.vectorDesc = vectorDesc;
+  }
+
+  public VectorMapJoinDesc getVectorDesc() {
+    return vectorDesc;
+  }
+
   private void initRetainExprList() {
     retainList = new HashMap<Byte, List<Integer>>();
     Set<Entry<Byte, List<ExprNodeDesc>>> set = super.getExprs().entrySet();

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/java/org/apache/hadoop/hive/ql/plan/VectorMapJoinDesc.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/plan/VectorMapJoinDesc.java b/ql/src/java/org/apache/hadoop/hive/ql/plan/VectorMapJoinDesc.java
new file mode 100644
index 0000000..e1bf1f4
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/plan/VectorMapJoinDesc.java
@@ -0,0 +1,107 @@
+/**
+ * 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.hadoop.hive.ql.plan;
+
+/**
+ * VectorGroupByDesc.
+ *
+ * Extra parameters beyond MapJoinDesc just for the vector map join operators.
+ *
+ * We don't extend MapJoinDesc because the base OperatorDesc doesn't support
+ * clone and adding it is a lot work for little gain.
+ */
+public class VectorMapJoinDesc extends AbstractVectorDesc  {
+
+  private static long serialVersionUID = 1L;
+
+  public static enum HashTableImplementationType {
+    NONE,
+    OPTIMIZED,
+    FAST
+  }
+
+  public static enum HashTableKind {
+    NONE,
+    HASH_SET,
+    HASH_MULTISET,
+    HASH_MAP
+  }
+
+  public static enum HashTableKeyType {
+    NONE,
+    BOOLEAN,
+    BYTE,
+    SHORT,
+    INT,
+    LONG,
+    STRING,
+    MULTI_KEY
+  }
+
+  private HashTableImplementationType hashTableImplementationType;
+  private HashTableKind hashTableKind;
+  private HashTableKeyType hashTableKeyType;
+  private boolean minMaxEnabled;
+
+  public VectorMapJoinDesc() {
+    hashTableImplementationType = HashTableImplementationType.NONE;
+    hashTableKind = HashTableKind.NONE;
+    hashTableKeyType = HashTableKeyType.NONE;
+    minMaxEnabled = false;
+  }
+
+  public VectorMapJoinDesc(VectorMapJoinDesc clone) {
+    this.hashTableImplementationType = clone.hashTableImplementationType;
+    this.hashTableKind = clone.hashTableKind;
+    this.hashTableKeyType = clone.hashTableKeyType;
+    this.minMaxEnabled = clone.minMaxEnabled;
+  }
+
+  public HashTableImplementationType hashTableImplementationType() {
+    return hashTableImplementationType;
+  }
+
+  public void setHashTableImplementationType(HashTableImplementationType hashTableImplementationType) {
+    this.hashTableImplementationType = hashTableImplementationType;
+  }
+
+  public HashTableKind hashTableKind() {
+    return hashTableKind;
+  }
+
+  public void setHashTableKind(HashTableKind hashTableKind) {
+    this.hashTableKind = hashTableKind;
+  }
+
+  public HashTableKeyType hashTableKeyType() {
+    return hashTableKeyType;
+  }
+
+  public void setHashTableKeyType(HashTableKeyType hashTableKeyType) {
+    this.hashTableKeyType = hashTableKeyType;
+  }
+
+  public boolean minMaxEnabled() {
+    return minMaxEnabled;
+  }
+
+  public void setMinMaxEnabled(boolean minMaxEnabled) {
+    this.minMaxEnabled = minMaxEnabled;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/TestDebugDisplay.java
----------------------------------------------------------------------
diff --git a/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/TestDebugDisplay.java b/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/TestDebugDisplay.java
new file mode 100644
index 0000000..2a4f409
--- /dev/null
+++ b/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/TestDebugDisplay.java
@@ -0,0 +1,63 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit test for the vectorized conversion to and from row object[].
+ */
+public class TestDebugDisplay extends TestCase {
+
+  public void testDebugDisplay() throws Throwable {
+
+  try {
+    String result;
+    int[] test0 = {};
+    result = VectorMapJoinGenerateResultOperator.intArrayToRangesString(test0, test0.length);
+    System.out.println(result);
+    int[] test1 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
+    result = VectorMapJoinGenerateResultOperator.intArrayToRangesString(test1, test1.length);
+    System.out.println(result);
+    int[] test2 = {5};
+    result = VectorMapJoinGenerateResultOperator.intArrayToRangesString(test2, test2.length);
+    System.out.println(result);
+    int[] test3 = {4,4};
+    result = VectorMapJoinGenerateResultOperator.intArrayToRangesString(test3, test3.length);
+    System.out.println(result);
+    int[] test4 = {0,1,2,3,4,5,6,6,7,7,8};
+    result = VectorMapJoinGenerateResultOperator.intArrayToRangesString(test4, test4.length);
+    System.out.println(result);
+    int[] test5 = {0,0,1};
+    result = VectorMapJoinGenerateResultOperator.intArrayToRangesString(test5, test5.length);
+    System.out.println(result);
+    int[] test6 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
+    result = VectorMapJoinGenerateResultOperator.intArrayToRangesString(test6, test6.length);
+    System.out.println(result);
+    int[] test7 = {4,2};
+    result = VectorMapJoinGenerateResultOperator.intArrayToRangesString(test7, test7.length);
+    System.out.println(result);
+
+
+  } catch (Throwable e) {
+    e.printStackTrace();
+    throw e;
+  }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/CommonFastHashTable.java
----------------------------------------------------------------------
diff --git a/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/CommonFastHashTable.java b/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/CommonFastHashTable.java
new file mode 100644
index 0000000..c2375e0
--- /dev/null
+++ b/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/CommonFastHashTable.java
@@ -0,0 +1,128 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.fast;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.hadoop.hive.ql.exec.vector.mapjoin.hashtable.VectorMapJoinHashMapResult;
+import org.apache.hadoop.hive.serde2.WriteBuffers;
+
+import static org.junit.Assert.*;
+
+public class CommonFastHashTable {
+
+  protected static final float LOAD_FACTOR = 0.75f;
+  protected static final int CAPACITY = 8;
+  protected static final int WB_SIZE = 128; // Make sure we cross some buffer boundaries...
+  protected static final int MODERATE_WB_SIZE = 8 * 1024;
+  protected static final int MODERATE_CAPACITY = 512;
+  protected static final int LARGE_WB_SIZE = 1024 * 1024;
+  protected static final int LARGE_CAPACITY = 8388608;
+  protected static Random random;
+
+  public static int generateLargeCount() {
+    int count = 0;
+    if (random.nextInt(100) != 0) {
+      switch (random.nextInt(5)) {
+      case 0:
+        count = 1;
+        break;
+      case 1:
+        count = 2;
+        break;
+      case 2:
+        count = 3;
+      case 3:
+        count = 4 + random.nextInt(7);
+        break;
+      case 4:
+        count = 10 + random.nextInt(90);
+        break;
+      default:
+        throw new Error("Missing case");
+      }
+    } else {
+      switch (random.nextInt(3)) {
+      case 0:
+        count = 100 + random.nextInt(900);
+        break;
+      case 1:
+        count = 1000 + random.nextInt(9000);
+        break;
+      case 2:
+        count = 10000 + random.nextInt(90000);
+        break;
+      }
+    }
+    return count;
+  }
+  public static void verifyHashMapResult(VectorMapJoinHashMapResult hashMapResult,
+      RandomByteArrayStream randomByteArrayStream ) {
+
+    List<byte[]> resultBytes = new ArrayList<byte[]>();
+    int count = 0;
+    if (hashMapResult.hasRows()) {
+      WriteBuffers.ByteSegmentRef ref = hashMapResult.first();
+      while (ref != null) {
+        count++;
+        byte[] bytes = ref.getBytes();
+        int offset = (int) ref.getOffset();
+        int length = ref.getLength();
+        resultBytes.add(Arrays.copyOfRange(bytes, offset, offset + length));
+        ref = hashMapResult.next();
+      }
+    } else {
+      assertTrue(hashMapResult.isEof());
+    }
+    if (randomByteArrayStream.size() != count) {
+      assertTrue(false);
+    }
+
+    for (int i = 0; i < count; ++i) {
+      byte[] bytes = resultBytes.get(i);
+      if (!randomByteArrayStream.contains(bytes)) {
+        assertTrue(false);
+      }
+    }
+  }
+
+  public static void verifyHashMapResult(VectorMapJoinHashMapResult hashMapResult,
+      byte[] valueBytes ) {
+
+    assertTrue(hashMapResult.hasRows());
+    WriteBuffers.ByteSegmentRef ref = hashMapResult.first();
+    byte[] bytes = ref.getBytes();
+    int offset = (int) ref.getOffset();
+    int length = ref.getLength();
+    assertTrue(valueBytes.length == length);
+    boolean match = true;  // Assume
+    for (int j = 0; j < length; j++) {
+      if (valueBytes[j] != bytes[offset + j]) {
+        match = false;
+        break;
+      }
+    }
+    if (!match) {
+      assertTrue(false);
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/RandomByteArrayStream.java
----------------------------------------------------------------------
diff --git a/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/RandomByteArrayStream.java b/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/RandomByteArrayStream.java
new file mode 100644
index 0000000..3960272
--- /dev/null
+++ b/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/RandomByteArrayStream.java
@@ -0,0 +1,92 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.fast;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+public class RandomByteArrayStream {
+
+  private Random random;
+  private int min;
+
+  private List<byte[]> byteArrays;
+
+  public RandomByteArrayStream(Random random) {
+    this.random = random;
+    byteArrays = new ArrayList<byte[]>();
+    min = 1;
+  }
+
+  public RandomByteArrayStream(Random random, int min) {
+    this.random = random;
+    byteArrays = new ArrayList<byte[]>();
+    this.min = min;
+  }
+
+  public byte[] next() {
+    int category = random.nextInt(100);
+    int count = 0;
+    if (category < 98) {
+      count = min + random.nextInt(10);
+    } else {
+      switch (category - 98) {
+      case 0:
+        count = Math.max(min, 10) + random.nextInt(90);
+        break;
+      case 1:
+        count = Math.max(min, 100) + random.nextInt(900);
+      }
+    }
+    byte[] bytes = new byte[count];
+    random.nextBytes(bytes);
+    byteArrays.add(bytes);
+    return bytes;
+  }
+
+  public int size() {
+    return byteArrays.size();
+  }
+
+  public byte[] get(int i) {
+    return byteArrays.get(i);
+  }
+
+  public boolean contains(byte[] bytes) {
+    int length = bytes.length;
+    for (int i = 0; i < byteArrays.size(); i++) {
+      byte[] streamBytes = byteArrays.get(i);
+      if (streamBytes.length != length) {
+        continue;
+      }
+      boolean match = true;  // Assume
+      for (int j = 0 ; j < length; j++) {
+        if (streamBytes[j] != bytes[j]) {
+          match = false;
+          break;
+        }
+      }
+      if (match) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/d47995d9/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/RandomLongStream.java
----------------------------------------------------------------------
diff --git a/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/RandomLongStream.java b/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/RandomLongStream.java
new file mode 100644
index 0000000..eab5c21
--- /dev/null
+++ b/ql/src/test/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/RandomLongStream.java
@@ -0,0 +1,49 @@
+/**
+ * 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.hadoop.hive.ql.exec.vector.mapjoin.fast;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+public class RandomLongStream {
+
+  private Random random;
+
+  private List<Long> longs;
+
+  public RandomLongStream(Random random) {
+    this.random = random;
+    longs = new ArrayList<Long>();
+  }
+
+  public long next() {
+    long longValue = random.nextLong();
+    longs.add(longValue);
+    return longValue;
+  }
+
+  public int size() {
+    return longs.size();
+  }
+
+  public long get(int i) {
+    return longs.get(i);
+  }
+}
\ No newline at end of file


Mime
View raw message