private void drainAndLoadForPartition(int partitionId, VectorMapJoinFastTableContainer tableContainer)
      throws InterruptedException, IOException, HiveException, SerDeException {
    LOG.info("Starting draining thread {}", partitionId);
    long totalProcessedEntries = 0;
    HashTableElementBatch batch = null;
    while (batch != DONE_SENTINEL) {
      batch = this.loadBatchQueues[partitionId].take();
      LOG.debug("Draining thread {} batchSize {}", partitionId, batch.getSize());
      for (int i = 0; i < batch.getSize(); i++) {
        try {
          HashTableElement h = batch.getBatch(i);
          tableContainer.putRow(h.getHashCode(), h.getKey(), h.getValue());
        }
        catch (Exception e) {
          throw new HiveException("Exception in draining thread put row", e);
        }
      }
      totalProcessedEntries += batch.getSize();
      LOG.debug("Draining thread {} added {} entries", partitionId, batch.getSize());
      totalEntries.accumulate(batch.getSize());
      // Offer must be at the end as it is resetting the Index(size)
      this.batchPool.offer(batch);
    }

    LOG.info("Terminating draining thread {} after processing Entries {}", partitionId, totalProcessedEntries);
  }
HashTableLoader for Tez constructs the hashtable from records read from
a broadcast edge.
ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/fast/VectorMapJoinFastHashTableLoader.java