// 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.
#pragma once

#include <cstdint>
#include <cstring>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <glog/logging.h>

#include "kudu/common/columnblock.h"
#include "kudu/common/rowblock_memory.h"
#include "kudu/common/schema.h"
#include "kudu/common/types.h"
#include "kudu/gutil/macros.h"
#include "kudu/gutil/strings/stringpiece.h"
#include "kudu/util/bitmap.h"
#include "kudu/util/status.h"

namespace kudu {

class Arena;
class RowBlockRow;
class SelectedRows;

// Bit-vector representing the selection status of each row in a row block.
//
// When scanning through data, a 1 bit in the selection vector indicates that
// the given row is live and has passed all predicates.
class SelectionVector {
 public:
  // Construct a new vector. The bits are initially in an indeterminate state.
  // Call SetAllTrue() if you require all rows to be initially selected.
  explicit SelectionVector(size_t row_capacity);

  // Construct a vector which shares the underlying memory of another vector,
  // but only exposes up to a given prefix of the number of rows.
  //
  // Note that mutating the resulting bitmap may arbitrarily mutate the "extra"
  // bits of the 'other' bitmap.
  //
  // The underlying bytes must not be deallocated or else this object will become
  // invalid.
  SelectionVector(SelectionVector *other, size_t prefix_rows);

  // Resize the selection vector to the given number of rows.
  // This size must be <= the allocated capacity.
  //
  // Ensures that all rows for indices < n_rows are unmodified.
  void Resize(size_t n_rows);

  // Zeroes out the end of the selection vector such that it will be left with
  // at most 'max_rows' selected.
  //
  // If 'max_rows' is greater than the allocated capacity, this does nothing.
  void ClearToSelectAtMost(size_t max_rows);

  // Return the number of selected rows.
  size_t CountSelected() const;

  // Return true if any rows are selected, false if size 0.
  // This is equivalent to (CountSelected() > 0), but faster.
  bool AnySelected() const;

  bool IsRowSelected(size_t row) const {
    DCHECK_LT(row, n_rows_);
    return BitmapTest(&bitmap_[0], row);
  }

  void SetRowSelected(size_t row) {
    DCHECK_LT(row, n_rows_);
    BitmapSet(&bitmap_[0], row);
  }

  void SetRowUnselected(size_t row) {
    DCHECK_LT(row, n_rows_);
    BitmapClear(&bitmap_[0], row);
  }

  // Finds the first selected row beginning at 'row_offset'.
  //
  // Returns true if at least one row is selected and writes its index to 'row';
  // returns false otherwise.
  bool FindFirstRowSelected(size_t row_offset, size_t* row) {
    DCHECK_LT(row_offset, n_rows_);
    DCHECK(row);
    return BitmapFindFirstSet(&bitmap_[0], row_offset, n_rows_, row);
  }

  // Processes the selection vector to return a SelectedRows object which indicates
  // the indices of the selected rows. The returned object refers to the memory
  // of this SelectionVector and must not be retained longer than this instance.
  SelectedRows GetSelectedRows() const;

  uint8_t *mutable_bitmap() {
    return &bitmap_[0];
  }

  const uint8_t *bitmap() const {
    return &bitmap_[0];
  }

  // Set all bits in the bitmap to 1
  void SetAllTrue() {
    memset(&bitmap_[0], 0xff, n_bytes_);
    PadExtraBitsWithZeroes();
  }

  // Set all bits in the bitmap to 0
  void SetAllFalse() {
    memset(&bitmap_[0], 0, n_bytes_);
  }

  size_t nrows() const { return n_rows_; }

  // Copies a range of bits between two SelectionVectors.
  //
  // The extent of the range is designated by 'src_row_off' and 'num_rows'. It
  // is copied to 'dst' at 'dst_row_off'.
  //
  // Note: 'dst' will be resized if the copy causes it to grow (though this is
  // just a "logical" resize; no reallocation takes place).
  void CopyTo(SelectionVector* dst, size_t src_row_off,
              size_t dst_row_off, size_t num_rows) const {
    DCHECK_GE(n_rows_, src_row_off + num_rows);

    size_t new_num_rows = dst_row_off + num_rows;
    if (new_num_rows > dst->nrows()) {
      // This will crash if 'dst' lacks adequate capacity.
      dst->Resize(new_num_rows);
    }

    BitmapCopy(dst->mutable_bitmap(), dst_row_off,
               bitmap_.get(), src_row_off, num_rows);
  }

  std::string ToString() const {
    return BitmapToString(&bitmap_[0], n_rows_);
  }

 private:

  // Pads any non-byte-aligned bits at the end of the SelectionVector with zeroes.
  //
  // To improve performance, CountSelected() and AnySelected() evaluate the
  // SelectionVector's bitmap in terms of bytes. As such, they consider all of
  // the trailing bits, even if the bitmap's bit length is not byte-aligned and
  // some trailing bits aren't part of the bitmap.
  //
  // To address this without sacrificing performance, we need to zero out all
  // trailing bits at construction time, or after any operation that sets all
  // bytes in bulk.
  void PadExtraBitsWithZeroes() {
    size_t bits_in_last_byte = n_rows_ & 7;
    if (bits_in_last_byte > 0) {
      BitmapChangeBits(&bitmap_[0], n_rows_, 8 - bits_in_last_byte, false);
    }
  }

  // The number of allocated bytes in bitmap_
  size_t bytes_capacity_;

  size_t n_rows_;
  size_t n_bytes_;

  std::unique_ptr<uint8_t[]> bitmap_;

  DISALLOW_COPY_AND_ASSIGN(SelectionVector);
};

bool operator==(const SelectionVector& a, const SelectionVector& b);
bool operator!=(const SelectionVector& a, const SelectionVector& b);

// A SelectionVectorView keeps track of where in the selection vector a given
// batch will start from. After processing a batch, Advance() should be called
// and the view will move forward by the appropriate amount. In this way, the
// underlying selection vector can easily be updated batch-by-batch.
class SelectionVectorView {
 public:
  // Constructs a new SelectionVectorView.
  //
  // The 'sel_vec' object must outlive this SelectionVectorView.
  explicit SelectionVectorView(SelectionVector *sel_vec)
    : sel_vec_(sel_vec), row_offset_(0) {
  }
  void Advance(size_t skip) {
    DCHECK_LE(skip, sel_vec_->nrows() - row_offset_);
    row_offset_ += skip;
  }
  void SetBit(size_t row_idx) {
    DCHECK_LE(row_idx, sel_vec_->nrows() - row_offset_);
    BitmapSet(sel_vec_->mutable_bitmap(), row_offset_ + row_idx);
  }
  void ClearBit(size_t row_idx) {
    DCHECK_LE(row_idx, sel_vec_->nrows() - row_offset_);
    BitmapClear(sel_vec_->mutable_bitmap(), row_offset_ + row_idx);
  }
  bool TestBit(size_t row_idx) {
    DCHECK_LE(row_idx, sel_vec_->nrows() - row_offset_);
    return BitmapTest(sel_vec_->bitmap(), row_offset_ + row_idx);
  }
  // Clear "nrows" bits from the supplied "offset" in the current view.
  void ClearBits(size_t nrows, size_t offset = 0) {
    DCHECK_LE(offset + nrows, sel_vec_->nrows() - row_offset_);
    BitmapChangeBits(sel_vec_->mutable_bitmap(), row_offset_ + offset, nrows, false);
  }
 private:
  SelectionVector* sel_vec_;
  size_t row_offset_;
};

// Result type for SelectionVector::GetSelectedRows.
class SelectedRows {
 public:
  bool all_selected() const {
    return all_selected_;
  }

  int num_selected() const {
    return all_selected_ ? sel_vector_->nrows() : indexes_.size();
  }

  // Get the selected rows.
  //
  // NOTE: callers must check all_selected() first, and not use this
  // function if all rows are selected. 'AsRowIndexes()' may be used instead.
  const std::vector<uint16_t>& indexes() const {
    DCHECK(!all_selected_);
    return indexes_;
  }

  const uint8_t* bitmap() const {
    return sel_vector_->bitmap();
  }

  // Convert this object to a simple vector of row indexes, materializing that
  // vector in the case that all of the rows are selected.
  std::vector<uint16_t> ToRowIndexes() && {
    if (!all_selected_) {
      return std::move(indexes_);
    }
    return CreateRowIndexes();
  }

  // Call F(index) for each selected index.
  template<class F>
  void ForEachIndex(F func) const {
    if (all_selected_) {
      int n_sel = num_selected();
      for (int i = 0; i < n_sel; i++) {
        func(i);
      }
    } else {
      for (uint16_t i : indexes_) {
        func(i);
      }
    }
  }

 private:
  friend class SelectionVector;

  explicit SelectedRows(const SelectionVector* sel_vector)
      : sel_vector_(sel_vector),
        all_selected_(true) {
  }
  explicit SelectedRows(const SelectionVector* sel_vector,
                        std::vector<uint16_t> indexes)
      : sel_vector_(sel_vector),
        all_selected_(false),
        indexes_(std::move(indexes)) {
  }

  std::vector<uint16_t> CreateRowIndexes();

  const SelectionVector* const sel_vector_;
  const bool all_selected_;
  std::vector<uint16_t> indexes_;
};

// A block of decoded rows.
// Wrapper around a buffer, which keeps the buffer's size, associated arena,
// and schema. Provides convenience accessors for indexing by row, column, etc.
//
// NOTE: TODO: We don't have any separate class for ConstRowBlock and ConstColumnBlock
// vs RowBlock and ColumnBlock. So, we use "const" in various places to either
// mean const-ness of the wrapper structure vs const-ness of the referred-to data.
// Typically in C++ this is done with separate wrapper classes for const vs non-const
// referred-to data, but that would require a lot of duplication elsewhere in the code,
// so for now, we just use convention: if you have a RowBlock or ColumnBlock parameter
// that you expect to be modifying, use a "RowBlock *param". Otherwise, use a
// "const RowBlock& param". Just because you _could_ modify the referred-to contents
// of the latter doesn't mean you _should_.
class RowBlock {
 public:
  // Constructs a new RowBlock.
  //
  // The 'schema' and 'arena' objects must outlive this RowBlock.
  RowBlock(const Schema* schema, size_t nrows, RowBlockMemory* memory);
  ~RowBlock();

  // Resize the block to the given number of rows.
  // This size must be <= the the allocated capacity row_capacity().
  //
  // Ensures that all rows for indices < n_rows are unmodified.
  void Resize(size_t n_rows);

  size_t row_capacity() const {
    return row_capacity_;
  }

  RowBlockRow row(size_t idx) const;

  const Schema* schema() const { return schema_; }
  Arena* arena() const { return &DCHECK_NOTNULL(memory_)->arena; }

  ColumnBlock column_block(size_t col_idx) const {
    return column_block(col_idx, nrows_);
  }

  ColumnBlock column_block(size_t col_idx, size_t nrows) const {
    DCHECK_LE(nrows, nrows_);

    const ColumnSchema& col_schema = schema_->column(col_idx);
    uint8_t* col_data = columns_data_[col_idx];
    uint8_t* nulls_bitmap = column_non_null_bitmaps_[col_idx];

    return ColumnBlock(col_schema.type_info(), nulls_bitmap, col_data, nrows, memory_);
  }

  // Return the base pointer for the given column's data.
  //
  // This is used by the codegen code in preference to the "nicer" column_block APIs,
  // because the codegenned code knows the column's type sizes statically, and thus
  // computing the pointers by itself ends up avoiding a multiply instruction.
  uint8_t* column_data_base_ptr(size_t col_idx) const {
    DCHECK_LT(col_idx, columns_data_.size());
    return columns_data_[col_idx];
  }

  // Return the number of rows in the row block. Note that this includes
  // rows which were filtered out by the selection vector.
  size_t nrows() const { return nrows_; }

  // Zero the memory pointed to by this row block.
  // This physically zeros the memory, so is not efficient - mostly useful
  // from unit tests.
  void ZeroMemory() {
    size_t bitmap_size = BitmapSize(row_capacity_);
    for (size_t i = 0; i < schema_->num_columns(); ++i) {
      const ColumnSchema& col_schema = schema_->column(i);
      size_t col_size = col_schema.type_info()->size() * row_capacity_;
      memset(columns_data_[i], '\0', col_size);

      if (column_non_null_bitmaps_[i] != NULL) {
        memset(column_non_null_bitmaps_[i], '\0', bitmap_size);
      }
    }
  }

  // Return the selection vector which indicates which rows have passed
  // predicates so far during evaluation of this block of rows.
  //
  // At the beginning of each batch, the vector is set to all 1s, and
  // as predicates or deletions make rows invalid, they are set to 0s.
  // After a batch has completed, only those rows with associated true
  // bits in the selection vector are valid results for the scan.
  SelectionVector* selection_vector() {
    return &sel_vec_;
  }

  const SelectionVector* selection_vector() const {
    return &sel_vec_;
  }

  // Copies a range of rows between two RowBlocks.
  //
  // The extent of the range is designated by 'src_row_off' and 'num_rows'. It
  // is copied to 'dst' at 'dst_row_off'.
  //
  // Note: 'dst' will be resized if the copy causes it to grow (though this is
  // just a "logical" resize; no reallocation takes place).
  Status CopyTo(RowBlock* dst, size_t src_row_off,
                size_t dst_row_off, size_t num_rows) const {
    DCHECK_SCHEMA_EQ(*schema_, *dst->schema());
    DCHECK_GE(nrows_, src_row_off + num_rows);

    size_t new_num_rows = dst_row_off + num_rows;
    if (new_num_rows > dst->nrows()) {
      // This will crash if 'dst' lacks adequate capacity.
      dst->Resize(new_num_rows);
    }

    for (size_t col_idx = 0; col_idx < schema_->num_columns(); col_idx++) {
      ColumnBlock src_cb(column_block(col_idx));
      ColumnBlock dst_cb(dst->column_block(col_idx));
      RETURN_NOT_OK(src_cb.CopyTo(sel_vec_, &dst_cb,
                                  src_row_off, dst_row_off, num_rows));
    }

    sel_vec_.CopyTo(&dst->sel_vec_, src_row_off, dst_row_off, num_rows);
    return Status::OK();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(RowBlock);

  static size_t RowBlockSize(const Schema& schema, size_t nrows) {
    size_t block_size = schema.num_columns() * sizeof(size_t);
    size_t bitmap_size = BitmapSize(nrows);
    for (size_t col = 0; col < schema.num_columns(); col++) {
      const ColumnSchema& col_schema = schema.column(col);
      block_size += nrows * col_schema.type_info()->size();
      if (col_schema.is_nullable())
        block_size += bitmap_size;
    }
    return block_size;
  }

  const Schema* schema_;
  std::vector<uint8_t*> columns_data_;
  std::vector<uint8_t*> column_non_null_bitmaps_;

  // The maximum number of rows that can be stored in our allocated buffer.
  size_t row_capacity_;

  // The number of rows currently being processed in this block.
  // nrows_ <= row_capacity_
  size_t nrows_;

  RowBlockMemory* memory_;

  // The bitmap indicating which rows are valid in this block.
  // Deleted rows or rows which have failed to pass predicates will be zeroed
  // in the bitmap, and thus not returned to the end user.
  SelectionVector sel_vec_;
};

// Provides an abstraction to interact with a RowBlock row.
//  Example usage:
//    RowBlock row_block(schema, 10, NULL);
//    RowBlockRow row = row_block.row(5);       // Get row 5
//    void *cell_data = row.cell_ptr(3);        // Get column 3 of row 5
//    ...
class RowBlockRow {
 public:
  typedef ColumnBlock::Cell Cell;

  // Constructs a new RowBlockRow.
  //
  // The 'row_block' object must outlive this RowBlockRow.
  explicit RowBlockRow(const RowBlock* row_block = nullptr,
                       size_t row_index = 0)
    : row_block_(row_block), row_index_(row_index) {
  }

  RowBlockRow* Reset(const RowBlock* row_block, size_t row_index) {
    row_block_ = row_block;
    row_index_ = row_index;
    return this;
  }

  const RowBlock* row_block() const {
    return row_block_;
  }

  size_t row_index() const {
    return row_index_;
  }

  const Schema* schema() const {
    return row_block_->schema();
  }

  bool is_null(size_t col_idx) const {
    return column_block(col_idx).is_null(row_index_);
  }

  uint8_t* mutable_cell_ptr(size_t col_idx) const {
    return const_cast<uint8_t*>(cell_ptr(col_idx));
  }

  const uint8_t* cell_ptr(size_t col_idx) const {
    return column_block(col_idx).cell_ptr(row_index_);
  }

  const uint8_t* nullable_cell_ptr(size_t col_idx) const {
    return column_block(col_idx).nullable_cell_ptr(row_index_);
  }

  Cell cell(size_t col_idx) const {
    return row_block_->column_block(col_idx).cell(row_index_);
  }

  ColumnBlock column_block(size_t col_idx) const {
    return row_block_->column_block(col_idx);
  }

  // Mark this row as unselected in the selection vector.
  void SetRowUnselected() {
    // TODO(todd): const-ness issues since this class holds a const RowBlock*.
    // hack around this for now
    SelectionVector* vec = const_cast<SelectionVector*>(row_block_->selection_vector());
    vec->SetRowUnselected(row_index_);
  }

#ifndef NDEBUG
  void OverwriteWithPattern(StringPiece pattern) {
    const Schema* schema = row_block_->schema();
    for (size_t col = 0; col < schema->num_columns(); col++) {
      row_block_->column_block(col).OverwriteWithPattern(row_index_, pattern);
    }
  }
#endif

 private:
  const RowBlock* row_block_;
  size_t row_index_;
};

inline RowBlockRow RowBlock::row(size_t idx) const {
  return RowBlockRow(this, idx);
}

} // namespace kudu
