private static long hashTableDataSizeAdjustment(long numRows, List<ColStatistics> colStats) {
    long result = 0;

    if (numRows <= 0 || colStats == null || colStats.isEmpty()) {
      return result;
    }

    for (ColStatistics cs : colStats) {
      if (cs != null) {
        String colTypeLowerCase = cs.getColumnType().toLowerCase();
        long nonNullCount = cs.getNumNulls() > 0 ? numRows - cs.getNumNulls() + 1 : numRows;
        double overhead = 0;
        if (colTypeLowerCase.equals(serdeConstants.STRING_TYPE_NAME)
            || colTypeLowerCase.startsWith(serdeConstants.VARCHAR_TYPE_NAME)
            || colTypeLowerCase.startsWith(serdeConstants.CHAR_TYPE_NAME)) {
          overhead = JavaDataModel.get().lengthForStringOfLength(0);
        } else if (colTypeLowerCase.equals(serdeConstants.BINARY_TYPE_NAME)) {
          overhead = JavaDataModel.get().lengthForByteArrayOfSize(0);
        } else if (colTypeLowerCase.equals(serdeConstants.TIMESTAMP_TYPE_NAME) ||
            colTypeLowerCase.equals(serdeConstants.TIMESTAMPLOCALTZ_TYPE_NAME) ||
            colTypeLowerCase.startsWith(serdeConstants.DECIMAL_TYPE_NAME) ||
            colTypeLowerCase.equals(serdeConstants.DATE_TYPE_NAME)) {
          overhead = JavaDataModel.get().object();
        }
        result = StatsUtils.safeAdd(StatsUtils.safeMult(nonNullCount, overhead), result);
      }
    }

    return result;
  }
In data calculation logic, we include some overhead due to java object refs, etc.
However, this overhead may be different when storing values in hashtable for mapjoin.
Hence, we calculate a size adjustment to the original data size for a given input.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConvertJoinMapJoin.java