/*
 * 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.drill.exec.record;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Collection;
import java.util.Map;
import org.apache.drill.common.map.CaseInsensitiveMap;
import org.apache.drill.common.types.TypeProtos;
import org.apache.drill.common.types.TypeProtos.DataMode;
import org.apache.drill.common.types.TypeProtos.MinorType;
import org.apache.drill.exec.expr.TypeHelper;
import org.apache.drill.exec.memory.AllocationManager.BufferLedger;
import org.apache.drill.exec.memory.BaseAllocator;
import org.apache.drill.exec.record.selection.SelectionVector2;
import org.apache.drill.exec.vector.AllocationHelper;
import org.apache.drill.exec.vector.NullableVector;
import org.apache.drill.exec.vector.UInt1Vector;
import org.apache.drill.exec.vector.UInt4Vector;
import org.apache.drill.exec.vector.UntypedNullVector;
import org.apache.drill.exec.vector.ValueVector;
import org.apache.drill.exec.vector.complex.AbstractMapVector;
import org.apache.drill.exec.vector.complex.AbstractRepeatedMapVector;
import org.apache.drill.exec.vector.complex.RepeatedListVector;
import org.apache.drill.exec.vector.complex.RepeatedValueVector;
import org.apache.drill.exec.vector.VariableWidthVector;

import com.google.common.collect.Sets;
import org.apache.drill.exec.vector.complex.RepeatedVariableWidthVectorLike;
import org.bouncycastle.util.Strings;

import static org.apache.drill.exec.vector.AllocationHelper.STD_REPETITION_FACTOR;

/**
 * Given a record batch or vector container, determines the actual memory
 * consumed by each column, the average row, and the entire record batch.
 */

public class RecordBatchSizer {
  private static final int OFFSET_VECTOR_WIDTH = UInt4Vector.VALUE_WIDTH;
  private static final int BIT_VECTOR_WIDTH = UInt1Vector.VALUE_WIDTH;

  public static long multiplyByFactors(long size, double... factors)
  {
    double doubleSize = size;

    for (double factor: factors) {
      doubleSize *= factor;
    }

    return (long) doubleSize;
  }

  public static long multiplyByFactor(long size, double factor)
  {
    return (long) ((size) * factor);
  }

  /**
   * Column size information.
   */
  public class ColumnSize {
    public final String prefix;
    public final MaterializedField metadata;

    /**
     * This is the total size of just pure data for the column
     * for all entries.
     */

    private int totalDataSize;

    /**
     * This is the total size of data for the column + additional
     * metadata vector overhead we add for cardinality, variable length etc.
     * for all entries.
     */

    private int totalNetSize;

    /**
     * Number of occurrences of the value in the batch. This is trivial
     * for top-level scalars: it is the record count. For a top-level
     * repeated vector, this is the number of arrays, also the record
     * count. For a value nested inside a repeated map, it is the
     * total number of values across all maps, and may be less than,
     * greater than (but unlikely) same as the row count.
     */

    private final int valueCount;

    /**
     * Total number of elements for a repeated type, or same as
     * valueCount if this is a non-repeated type. That is, a batch
     * of 100 rows may have an array with 10 elements per row.
     * In this case, the element count is 1000.
     */

    private int elementCount;

    /**
     * The estimated, average number of elements per parent value.
     * Always 1 for a non-repeated type. For a repeated type,
     * this is the average entries per array (per repeated element).
     */

    private float cardinality;

    /**
     * Indicates if it is variable width column.
     * For map columns, this is true if any of the children is variable
     * width column.
     */

    private boolean isVariableWidth;

    /**
     * Indicates if cardinality is repeated(top level only).
     */

    private boolean isRepeated;

    /**
     * Indicates if cardinality is optional i.e. nullable(top level only).
     */
    private boolean isOptional;

    /**
     * Child columns if this is a map column.
     */
    private final Map<String, ColumnSize> children = CaseInsensitiveMap.newHashMap();

    /**
     * Returns true if there is an accurate std size. Otherwise it returns false.
     * @return True if there is an accurate std size. Otherwise it returns false.
     */
    public boolean hasStdDataSize() {
      return !isVariableWidth && !isRepeated;
    }

    /**
     * std pure data size per entry from Drill metadata, based on type.
     * Does not include metadata vector overhead we add for cardinality,
     * variable length etc.
     * For variable-width columns, we use 50 as std size for entry width.
     * For repeated column, we assume repetition of 10.
     */
    public int getStdDataSizePerEntry() {
      int stdDataSize;

      try {
        stdDataSize = TypeHelper.getSize(metadata.getType());

        // For variable width, typeHelper includes offset vector width. Adjust for that.
        if (isVariableWidth) {
          stdDataSize -= OFFSET_VECTOR_WIDTH;
        }

        if (isRepeated) {
          stdDataSize = stdDataSize * STD_REPETITION_FACTOR;
        }
      } catch (Exception e) {
        // For unsupported types, just set stdSize to 0.
        // Map, Union, List etc.
        stdDataSize = 0;
      }

      // Add sizes of children.
      for (ColumnSize columnSize : children.values()) {
        stdDataSize += columnSize.getStdDataSizePerEntry();
      }

      if (isRepeatedList()) {
        stdDataSize = stdDataSize * STD_REPETITION_FACTOR;
      }

      return stdDataSize;
    }

    /**
     * std net size per entry taking into account additional metadata vectors
     * we add on top for variable length, cardinality etc.
     * For variable-width columns, we use 50 as std data size for entry width.
     * For repeated column, we assume repetition of 10.
     */
    public int getStdNetSizePerEntry() {
      return getStdNetSizePerEntryCommon(metadata.getType(), isOptional, isRepeated, isRepeatedList(), children);
    }

    /**
     * This is the average actual per entry data size in bytes. Does not
     * include any overhead of metadata vectors.
     * For repeated columns, it is average for the repeated array, not
     * individual entry in the array.
     */
    public int getDataSizePerEntry() {
      return safeDivide(getTotalDataSize(), getValueCount());
    }

    /**
     * This is the average per entry size of just pure data plus
     * overhead of additional vectors we add on top like bits vector,
     * offset vector etc. This
     * size is larger than the actual data size since this size includes per-
     * column overhead for additional vectors we add for
     * cardinality, variable length etc.
     */
    public int getNetSizePerEntry() {
      return safeDivide(getTotalNetSize(), getValueCount());
    }

    /**
     * This returns actual entry size if rowCount > 0 or allocation size otherwise.
     * Use this for the cases when you might get empty batches with schema
     * and you still need to do memory calculations based on just schema.
     */
    public int getAllocSizePerEntry() {
      if (rowCount() != 0) {
        return getNetSizePerEntry();
      }

      int stdNetSize;
      try {
        stdNetSize = TypeHelper.getSize(metadata.getType());

        // TypeHelper estimates 50 bytes for variable length. That is pretty high number
        // to use as approximation for empty batches. Use 8 instead.
        switch (metadata.getType().getMinorType()) {
          case VARBINARY:
          case VARCHAR:
          case VAR16CHAR:
          case VARDECIMAL:
            stdNetSize = 4 + 8;
            break;
          default:
        }
      } catch (Exception e) {
        stdNetSize = 0;
      }

      if (isOptional) {
        stdNetSize += BIT_VECTOR_WIDTH;
      }

      if (isRepeated) {
        stdNetSize = (stdNetSize * STD_REPETITION_FACTOR) + OFFSET_VECTOR_WIDTH;
      }

      for (ColumnSize columnSize : children.values()) {
        stdNetSize += columnSize.getAllocSizePerEntry();
      }

      if (isRepeatedList()) {
        stdNetSize = (stdNetSize * STD_REPETITION_FACTOR) + OFFSET_VECTOR_WIDTH;
      }

      return stdNetSize;
    }

    /**
     * If there is an accurate std net size, that is returned. Otherwise the net size is returned.
     * @return If there is an accurate std net size, that is returned. Otherwise the net size is returned.
     */
    public int getStdNetOrNetSizePerEntry() {
      if (hasStdDataSize()) {
        return getStdNetSizePerEntry();
      } else {
        return getNetSizePerEntry();
      }
    }

    /**
     * This is the total data size for the column, including children for map
     * columns. Does not include any overhead of metadata vectors.
     */
    public int getTotalDataSize() {
      int dataSize = this.totalDataSize;
      for (ColumnSize columnSize : children.values()) {
        dataSize += columnSize.getTotalDataSize();
      }
      return dataSize;
    }

    /**
     * This is the total net size for the column, including children for map
     * columns. Includes overhead of metadata vectors.
     */
    public int getTotalNetSize() {
      return this.totalNetSize;
    }

    public int getValueCount() {
      return valueCount;
    }

    public int getElementCount() {
      return elementCount;
    }

    public float getCardinality() {
      return cardinality;
    }

    public boolean isVariableWidth() {
      return isVariableWidth;
    }

    public Map<String, ColumnSize> getChildren() {
      return children;
    }

    public boolean isComplex() {
      switch (metadata.getType().getMinorType()) {
        case LIST:
        case MAP:
        case DICT:
        case UNION:
          return true;
        default:
          return false;
      }
    }

    public boolean isRepeatedList() {
      if (metadata.getType().getMinorType() == MinorType.LIST &&
        metadata.getDataMode() == DataMode.REPEATED) {
        return true;
      }
      return false;
    }

    /**
     * This is the average per entry width, used for vector allocation.
     */
    private int getEntryWidthForAlloc() {
      int width = 0;
      if (isVariableWidth) {
        width = getAllocSizePerEntry() - OFFSET_VECTOR_WIDTH;

        // Subtract out the bits (is-set) vector width
        if (isOptional) {
          width -= BIT_VECTOR_WIDTH;
        }

        if (isRepeated && rowCount() == 0) {
          return (safeDivide(width, STD_REPETITION_FACTOR));
        }
      }

      return (safeDivide(width, getEntryCardinalityForAlloc()));
    }

    /**
     * This is the average per entry cardinality, used for vector allocation.
     */
    private float getEntryCardinalityForAlloc() {
      return getCardinality() == 0 ? (isRepeated ? STD_REPETITION_FACTOR : 1) :getCardinality();
    }

    public ColumnSize(ValueVector v, String prefix) {
      this.prefix = prefix;
      valueCount = v.getAccessor().getValueCount();
      metadata = v.getField();
      isVariableWidth = (v instanceof VariableWidthVector || v instanceof RepeatedVariableWidthVectorLike);
      elementCount = valueCount;
      cardinality = valueCount == 0 ? 0 : 1;
      totalNetSize = v.getPayloadByteCount(valueCount);

      // Special case. For union and list vectors, it is very complex
      // to figure out raw data size. Make it same as net size.
      if (metadata.getType().getMinorType() == MinorType.UNION ||
        (metadata.getType().getMinorType() == MinorType.LIST && v.getField().getDataMode() != DataMode.REPEATED)) {
        totalDataSize = totalNetSize;
      }

      switch(v.getField().getDataMode()) {
        case REPEATED:
          isRepeated = true;
          elementCount  = getElementCount(v);
          cardinality = valueCount == 0 ? 0 : elementCount * 1.0f / valueCount;

          // For complex types, there is nothing more to do for top columns.
          // Data size is calculated recursively for children later.
          if (isComplex()) {
            return;
          }

          // Calculate pure data size.
          if (isVariableWidth) {
            VariableWidthVector dataVector = ((VariableWidthVector) ((RepeatedValueVector) v).getDataVector());
            totalDataSize = dataVector.getCurrentSizeInBytes();
          } else {
            ValueVector dataVector = ((RepeatedValueVector) v).getDataVector();
            totalDataSize = dataVector.getPayloadByteCount(elementCount);
          }

          break;
        case OPTIONAL:
          isOptional = true;

          // For complex types, there is nothing more to do for top columns.
          // Data size is calculated recursively for children later.
          if (isComplex()) {
            return;
          }

          // Calculate pure data size.
          if (isVariableWidth) {
            VariableWidthVector variableWidthVector = ((VariableWidthVector) ((NullableVector) v).getValuesVector());
            totalDataSize = variableWidthVector.getCurrentSizeInBytes();
          } else {
            // Another special case.
            if (v instanceof UntypedNullVector) {
              return;
            }
            totalDataSize = ((NullableVector) v).getValuesVector().getPayloadByteCount(valueCount);
          }
          break;

        case REQUIRED:
          // For complex types, there is nothing more to do for top columns.
          // Data size is calculated recursively for children later.
          if (isComplex()) {
            return;
          }

          // Calculate pure data size.
          if (isVariableWidth) {
            totalDataSize = ((VariableWidthVector) v).getCurrentSizeInBytes();
          } else {
            totalDataSize = v.getPayloadByteCount(valueCount);
          }
          break;

        default:
            break;
      }
    }

    private int getElementCount(ValueVector v) {
      // Repeated vectors are special: they have an associated offset vector
      // that changes the value count of the contained vectors.
      UInt4Vector offsetVector = ((RepeatedValueVector) v).getOffsetVector();
      int childCount = valueCount == 0 ? 0 : offsetVector.getAccessor().get(valueCount);

      return childCount;
    }

    private void allocateMap(AbstractMapVector map, int recordCount) {
      if (map instanceof AbstractRepeatedMapVector) {
        ((AbstractRepeatedMapVector) map).allocateOffsetsNew(recordCount);
          recordCount *= Math.round(getEntryCardinalityForAlloc());
        }

      for (ValueVector vector : map) {
        children.get(vector.getField().getName()).allocateVector(vector, recordCount);
      }
    }

    private void allocateRepeatedList(RepeatedListVector vector, int recordCount) {
      vector.allocateOffsetsNew(recordCount);
      recordCount *= Math.round(getEntryCardinalityForAlloc());
      ColumnSize child = children.get(vector.getField().getName());
      if (vector.getDataVector() != null) {
        child.allocateVector(vector.getDataVector(), recordCount);
      }
    }

    public void allocateVector(ValueVector vector, int recordCount) {
      if (vector instanceof AbstractMapVector) {
        allocateMap((AbstractMapVector) vector, recordCount);
        return;
      }

      if (vector instanceof RepeatedListVector) {
        allocateRepeatedList((RepeatedListVector) vector, recordCount);
        return;
      }

      AllocationHelper.allocate(vector, recordCount, getEntryWidthForAlloc(), getEntryCardinalityForAlloc());
    }

    @Override
    public String toString() {
      StringBuilder buf = new StringBuilder()
          .append(prefix)
          .append(metadata.getName())
          .append("(type: ")
          .append(metadata.getType().getMode().name())
          .append(" ")
          .append(metadata.getType().getMinorType().name())
          .append(", count: ")
          .append(valueCount);
      if (metadata.getDataMode() == DataMode.REPEATED) {
        buf.append(", elements: ")
           .append(elementCount)
           .append(", per-array: ")
           .append(cardinality);
      }
      buf.append(", Per entry: std data size: ")
         .append(getStdDataSizePerEntry())
         .append(", std net size: ")
         .append(getStdNetSizePerEntry())
         .append(", actual data size: ")
         .append(getDataSizePerEntry())
         .append(", actual net size: ")
         .append(getNetSizePerEntry())
         .append("  Totals: data size: ")
         .append(getTotalDataSize())
         .append(", net size: ")
         .append(getTotalNetSize())
         .append(")");
      return buf.toString();
    }

    /**
     * Add a single vector initializer to a collection for the entire batch.
     * Uses the observed column size information to predict the size needed
     * when allocating a new vector for the same data. Adds a hint only for
     * variable-width or repeated types; no extra information is needed for
     * fixed width, non-repeated columns.
     *
     * @param initializer the vector initializer to hold the hints
     * for this column
     */

    public void buildVectorInitializer(VectorInitializer initializer) {
      int width = 0;
      switch(metadata.getType().getMinorType()) {
      case VAR16CHAR:
      case VARBINARY:
      case VARCHAR:

        // Subtract out the offset vector width
        width = getNetSizePerEntry() - OFFSET_VECTOR_WIDTH;

        // Subtract out the bits (is-set) vector width
        if (metadata.getDataMode() == DataMode.OPTIONAL) {
          width -= BIT_VECTOR_WIDTH;
        }
        break;
      default:
        break;
      }
      String name = prefix + metadata.getName();
      if (metadata.getDataMode() == DataMode.REPEATED) {
        if (width > 0) {
          // Estimated width is width of entire column. Divide
          // by element count to get per-element size.
          initializer.variableWidthArray(name, width / cardinality, cardinality);
        } else {
          initializer.fixedWidthArray(name, cardinality);
        }
      }
      else if (width > 0) {
        initializer.variableWidth(name, width);
      }

      for (ColumnSize columnSize : children.values()) {
        columnSize.buildVectorInitializer(initializer);
      }
    }

  }

   public static int getStdNetSizePerEntryCommon(TypeProtos.MajorType majorType, boolean isOptional, boolean isRepeated,
                                                 boolean isRepeatedList, Map<String, ColumnSize> children) {
    int stdNetSize;
    try {
      stdNetSize = TypeHelper.getSize(majorType);
    } catch (Exception e) {
      stdNetSize = 0;
    }

    if (isOptional) {
      stdNetSize += BIT_VECTOR_WIDTH;
    }

    if (isRepeated) {
      stdNetSize = (stdNetSize * STD_REPETITION_FACTOR) + OFFSET_VECTOR_WIDTH;
    }

    if (children != null) {
      for (ColumnSize columnSize : children.values()) {
        stdNetSize += columnSize.getStdNetSizePerEntry();
      }
    }

    if (isRepeatedList) {
      stdNetSize = (stdNetSize * STD_REPETITION_FACTOR) + OFFSET_VECTOR_WIDTH;
    }

    return stdNetSize;
  }

  private ColumnSize getComplexColumn(String path) {
    String[] segments = Strings.split(path, '.');
    Map<String, ColumnSize> map = columnSizes;
    return getComplexColumnImpl(segments, 0, map);
  }

  private ColumnSize getComplexColumnImpl(String[] segments, int level, Map<String, ColumnSize> map) {
    ColumnSize result = map.get(segments[level]);
    if (result == null || level == segments.length - 1) {
      return result;
    }
    map = result.getChildren();
    if (map == null) {
      return null;
    }
    return getComplexColumnImpl(segments, level + 1, map);
  }

  public ColumnSize getColumn(String name) {
    final RecordBatchSizer.ColumnSize columnSize =  columnSizes.get(name);
    if (columnSize != null) {
      return columnSize;
    } else {
      return getComplexColumn(name);
    }
  }

  // This keeps information for only top level columns. Information for nested
  // columns can be obtained from children of topColumns.
  private final Map<String, ColumnSize> columnSizes = new QuoteInsensitiveMap(CaseInsensitiveMap.newHashMap());

  /**
   * This field is used by the convenience method {@link #columnsList()}.
   */
  private final List<ColumnSize> columnSizesList = new ArrayList<>();

  /**
   * Number of records (rows) in the batch.
   */
  private final int rowCount;
  /**
   * Actual batch size summing all buffers used to store data
   * for the batch.
   */
  private long accountedMemorySize;
  /**
   * Actual row width computed by dividing total batch memory by the
   * record count.
   */
  private int grossRowWidth;
  /**
   * Actual row width computed by summing columns. Use this if the
   * vectors are partially full; prevents overestimating row width.
   */
  private int netRowWidth;
  private int netRowWidthCap50;

  /**
   * actual row size if input is not empty. Otherwise, standard size.
   */
  private int rowAllocWidth;
  private int stdRowWidth;

  public SelectionVector2 sv2 = null;
  private int sv2Size;

  private int avgDensity;

  private final Set<BufferLedger> ledgers = Sets.newIdentityHashSet();

  private long netBatchSize;

  /**
   *  Maximum width of a column; used for memory estimation in case of Varchars
   */

  public int maxSize;

  /**
   *  Count the nullable columns; used for memory estimation
   */

  public int nullableCount;


  public RecordBatchSizer(RecordBatch batch) {
    this(batch,
      (batch.getSchema() == null ? null : (batch.getSchema().getSelectionVectorMode() == BatchSchema.SelectionVectorMode.TWO_BYTE ?
        batch.getSelectionVector2() : null)));
  }
  /**
   * Create empirical metadata for a record batch given a vector accessible
   * (basically, an iterator over the vectors in the batch.)
   *
   * @param va iterator over the batch's vectors
   */

  public RecordBatchSizer(VectorAccessible va) {
    this(va, null);
  }

  /**
   * Create empirical metadata for a record batch given a vector accessible
   * (basically, an iterator over the vectors in the batch) along with a
   * selection vector for those records. The selection vector is used to
   * pad the estimated row width with the extra two bytes needed per record.
   * The selection vector memory is added to the total memory consumed by
   * this batch.
   *
   * @param va iterator over the batch's vectors
   * @param sv2 selection vector associated with this batch
   */

  public RecordBatchSizer(VectorAccessible va, SelectionVector2 sv2) {
    rowCount = va.getRecordCount();
    for (VectorWrapper<?> vw : va) {
      ColumnSize colSize = measureColumn(vw.getValueVector(), "");
      columnSizes.put(vw.getField().getName(), colSize);
      columnSizesList.add(colSize);
      stdRowWidth += colSize.getStdDataSizePerEntry();
      netBatchSize += colSize.getTotalNetSize();
      maxSize = Math.max(maxSize, colSize.getTotalDataSize());
      if (colSize.metadata.isNullable()) {
        nullableCount++;
      }
      netRowWidth += colSize.getNetSizePerEntry();
    }
    this.sv2 = sv2;
  }

  public void applySv2() {
    if (sv2 == null) {
      return;
    }

    sv2Size = BaseAllocator.nextPowerOfTwo(2 * rowCount);
    avgDensity = safeDivide(netBatchSize * 100L, getActualSize());
    accountedMemorySize += sv2Size;
  }

  /**
   *  Round up (if needed) to the next power of 2 (only up to 64)
   * @param arg Number to round up (must be < 64)
   * @return power of 2 result
   */
  private int roundUpToPowerOf2(int arg) {
    if ( arg <= 2 ) { return 2; }
    if ( arg <= 4 ) { return 4; }
    if ( arg <= 8 ) { return 8; }
    if ( arg <= 16 ) { return 16; }
    if ( arg <= 32 ) { return 32; }
    return 64;
  }

  private ColumnSize measureColumn(ValueVector v, String prefix) {
    ColumnSize colSize = new ColumnSize(v, prefix);
    switch (v.getField().getType().getMinorType()) {
      case MAP:
      case DICT:
        // Maps consume no size themselves. However, their contained
        // vectors do consume space, so visit columns recursively.
        expandMap(colSize, v, prefix + v.getField().getName() + ".");
        break;
      case LIST:
        // complex ListVector cannot be casted to RepeatedListVector.
        // do not expand the list if it is not repeated mode.
        if (v.getField().getDataMode() == DataMode.REPEATED) {
          expandList(colSize, (RepeatedListVector) v, prefix + v.getField().getName() + ".");
        }
        break;
      default:
        v.collectLedgers(ledgers);
    }

    netRowWidthCap50 += ! colSize.isVariableWidth ? colSize.getNetSizePerEntry() :
        8 /* offset vector */ + roundUpToPowerOf2(Math.min(colSize.getNetSizePerEntry(),50));
        // above change 8 to 4 after DRILL-5446 is fixed

    return colSize;
  }

  private void expandMap(ColumnSize colSize, ValueVector mapVector, String prefix) {
    for (ValueVector vector : mapVector) {
      colSize.children.put(vector.getField().getName(), measureColumn(vector, prefix));
    }

    // For a repeated map, we need the memory for the offset vector (only).
    // Map elements are recursively expanded above.
    if (mapVector.getField().getDataMode() == DataMode.REPEATED) {
      ((RepeatedValueVector) mapVector).getOffsetVector().collectLedgers(ledgers);
    }
  }

  private void expandList(ColumnSize colSize, RepeatedListVector vector, String prefix) {
    colSize.children.put(vector.getField().getName(), measureColumn(vector.getDataVector(), prefix));

    // Determine memory for the offset vector (only).
    vector.collectLedgers(ledgers);
  }

  public static int safeDivide(long num, long denom) {
    if (denom == 0) {
      return 0;
    }
    return (int) Math.ceil((double) num / denom);
  }

  public static int safeDivide(int num, int denom) {
    if (denom == 0) {
      return 0;
    }
    return (int) Math.ceil((double) num / denom);
  }

  public static int safeDivide(int num, float denom) {
    if (denom == 0) {
      return 0;
    }
    return (int) Math.ceil((double) num / denom);
  }

  public static int safeDivide(int num, double denom) {
    if (denom == 0) {
      return 0;
    }
    return (int) Math.ceil(num / denom);
  }

  public int rowCount() { return rowCount; }

  public int getStdRowWidth() {
    if (stdRowWidth != 0) {
      return stdRowWidth;
    }

    for (ColumnSize columnSize : columnSizes.values()) {
      stdRowWidth += columnSize.getStdDataSizePerEntry();
    }

    return stdRowWidth;
  }

  public int getRowAllocWidth() {
    if (rowAllocWidth != 0) {
      return rowAllocWidth;
    }

    for (ColumnSize columnSize : columnSizes.values()) {
      rowAllocWidth += columnSize.getAllocSizePerEntry();
    }

    return rowAllocWidth;
  }

  public long getActualSize() {
    if (accountedMemorySize != 0) {
      return accountedMemorySize;
    }

    for (BufferLedger ledger : ledgers) {
      accountedMemorySize += ledger.getAccountedSize();
    }

    if (sv2 != null) {
      sv2Size = sv2.getBuffer(false).capacity();
      accountedMemorySize += sv2Size;
    }

    return accountedMemorySize;
  }

  public int getGrossRowWidth() {
    if (grossRowWidth != 0) {
      return grossRowWidth;
    }

    grossRowWidth = safeDivide(getActualSize(), rowCount);

    return grossRowWidth;
  }

  public int getAvgDensity() {
    return safeDivide(netBatchSize * 100L, getActualSize());
  }


  public int getNetRowWidth() { return netRowWidth; }
  public Map<String, ColumnSize> columns() { return columnSizes; }

  /**
   * This is a convenience method to get the sizes of columns in the same order that the corresponding value vectors
   * are stored within a {@link org.apache.drill.exec.record.VectorAccessible}.
   * @return The sizes of columns in the same order that the corresponding value vectors are stored within a
   * {@link org.apache.drill.exec.record.VectorAccessible}.
   */
  public List<ColumnSize> columnsList() { return columnSizesList; }

  /**
   * Compute the "real" width of the row, taking into account each varchar column size
   * (historically capped at 50, and rounded up to power of 2 to match drill buf allocation)
   * and null marking columns.
   * @return "real" width of the row
   */
  public int getNetRowWidthCap50() { return netRowWidthCap50 + nullableCount; }
  public boolean hasSv2() { return sv2 != null; }
  public long getNetBatchSize() { return netBatchSize; }
  public int getMaxAvgColumnSize() { return safeDivide(maxSize, rowCount); }

  @Override
  public String toString() {
    StringBuilder buf = new StringBuilder();

    buf.append("Batch size: {");
    buf.append( "  Records: " );
    buf.append(rowCount);
    buf.append(", Total size: ");
    buf.append(accountedMemorySize);
    buf.append(", Data size: ");
    buf.append(netBatchSize);
    buf.append(", Gross row width: ");
    buf.append(grossRowWidth);
    buf.append(", Net row width: ");
    buf.append(netRowWidth);
    buf.append(", Density: ");
    buf.append(avgDensity);
    buf.append("% }\n");

    buf.append("Batch schema & sizes: {\n");
    for (ColumnSize colSize : columnSizes.values()) {
      buf.append("  ");
      buf.append(colSize.toString());
      buf.append(" }\n");
    }
    buf.append(" }\n");
    return buf.toString();
  }

  /**
   * The column size information gathered here represents empirically-derived
   * schema metadata. Use that metadata to create an instance of a class that
   * allocates memory for new vectors based on the observed size information.
   * The caller provides the row count; the size information here provides
   * column widths and the number of elements in each array.
   */

  public VectorInitializer buildVectorInitializer() {
    VectorInitializer initializer = new VectorInitializer();
    for (ColumnSize colSize : columnSizes.values()) {
      colSize.buildVectorInitializer(initializer);
    }
    return initializer;
  }

  public void allocateVectors(VectorContainer container, int recordCount) {
    for (VectorWrapper<?> w : container) {
      ColumnSize colSize = columnSizes.get(w.getField().getName());
      colSize.allocateVector(w.getValueVector(), recordCount);
    }
  }

  /**
   * A map that can handle quoted and unquoted column names; ideally this logic temporary and
   * should be removed as soon as all readers standardize handling of missing columns. Quoted columns
   * have been added in DRILL-4264.
   */
  private static final class QuoteInsensitiveMap implements Map<String, ColumnSize> {
    /** Original Map */
    private final Map<String, ColumnSize> originalMap;

    private QuoteInsensitiveMap(Map<String, ColumnSize> originalMap) {
      this.originalMap = originalMap;
    }

    @Override
    public int size() {
      return originalMap.size();
    }

    @Override
    public boolean isEmpty() {
      return originalMap.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
      return originalMap.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
      return originalMap.containsValue(value);
    }

    @Override
    public ColumnSize get(Object key) {
      ColumnSize value = originalMap.get(key);

      if (value == null) {
        value = originalMap.get(quoteString(key));
      }
      return value;
    }

    @Override
    public ColumnSize put(String key, ColumnSize value) {
      return originalMap.put(key, value);
    }

    @Override
    public ColumnSize remove(Object key) {
      ColumnSize value = originalMap.remove(key);

      if (value == null) {
        value = originalMap.remove(quoteString(key));
      }
      return value;
    }

    @Override
    public void putAll(Map<? extends String, ? extends ColumnSize> m) {
      originalMap.putAll(m);
    }

    @Override
    public void clear() {
      originalMap.clear();
    }

    @Override
    public Set<String> keySet() {
      return originalMap.keySet();
    }

    @Override
    public Collection<ColumnSize> values() {
      return originalMap.values();
    }

    @Override
    public Set<Entry<String, ColumnSize>> entrySet() {
      return originalMap.entrySet();
    }

    private String quoteString(Object key) {
      if (key instanceof String) {
        return "`" + key + '`';
      }
      throw new IllegalArgumentException();
    }

  }
}
