<commit_before>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include <cstdlib>
#include <memory>
#include <new>
#include <type_traits>

#include <caf/deserializer.hpp>
#include <caf/serializer.hpp>

#include "vast/data.hpp"
#include "vast/detail/range.hpp"
#include "vast/policy/column_major.hpp"
#include "vast/policy/row_major.hpp"
#include "vast/table_slice.hpp"
#include "vast/value_index.hpp"
#include "vast/view.hpp"

namespace vast {

/// An implementation of `table_slice` that keeps all entries in a
/// two-dimensional matrix, allocated in a single chunk of memory. As a
/// consequence, this table slice cannot grow and users have to provide the
/// maximum size upfront.
template <class LayoutPolicy>
class matrix_table_slice final : public table_slice {
public:
  // -- constants --------------------------------------------------------------

  static constexpr auto class_id = LayoutPolicy::class_id;

  // -- member types -----------------------------------------------------------

  /// Base type.
  using super = table_slice;

  /// Unsigned integer type.
  using size_type = super::size_type;

  /// Iterator over stored elements in unspecified order.
  using iterator = data*;

  /// Iterator over stored elements in unspecified order.
  using const_iterator = const data*;

  /// Iterator over stored elements in column-first order.
  using column_iterator = typename LayoutPolicy::column_iterator;

  /// Iterator over stored elements in column-first order.
  using const_column_iterator = typename LayoutPolicy::const_column_iterator;

  // -- constructors, destructors, and assignment operators --------------------

  ~matrix_table_slice() {
    // The element blocks gets allocated alongside this object. Hence, we need
    // to destroy our elements manually.
    auto first = elements();
    auto last = elements() + rows_ + columns_;
    for (auto i = first; i != last; ++i)
      i->~data();
  }

  /// @warning leaves all elements uninitialized.
  static matrix_table_slice* make_uninitialized(record_type layout,
                                                size_t rows);

  static matrix_table_slice* make(record_type layout, size_t rows) {
    auto ptr = make_uninitialized(std::move(layout), rows);
    std::uninitialized_default_construct(ptr->begin(), ptr->end());
    return ptr;
  }

  // -- properties -------------------------------------------------------------

  matrix_table_slice* copy() const override {
    auto ptr = make_uninitialized(this->layout(), rows_);
    std::uninitialized_copy(begin(), end(), ptr->begin());
    return ptr;
  }

  caf::error serialize(caf::serializer& sink) const override {
    for (auto i = begin(); i != end(); ++i)
      if (auto err = sink(*i))
        return err;
    return caf::none;
  }

  caf::error deserialize(caf::deserializer& source) override {
    for (auto i = begin(); i != end(); ++i)
      if (auto err = source(*i))
        return err;
    return caf::none;
  }

  void apply_column(size_type col, value_index& idx) const override {
    auto row = offset();
    for (auto& x : column(col))
      idx.append(make_view(x), row++);
  }

  caf::atom_value implementation_id() const noexcept override {
    return class_id;
  }

  data_view at(size_type row, size_type col) const override {
    auto ptr = elements();
    return make_view(ptr[LayoutPolicy::index_of(rows_, columns_, row, col)]);
  }

  iterator begin() {
    return elements();
  }

  iterator end() {
    return begin() + rows_ * columns_;
  }

  const_iterator begin() const {
    return elements();
  }

  const_iterator end() const {
    return begin() + rows_ * columns_;
  }

  /// Returns the range representing the column at position `pos`.
  detail::iterator_range<column_iterator> column(size_type pos) {
    auto first = LayoutPolicy::make_column_iterator(elements(), rows_, pos);
    return {first, first + columns_};
  }

  /// Returns the range representing the column at position `pos`.
  detail::iterator_range<const_column_iterator> column(size_type pos) const {
    auto first = LayoutPolicy::make_column_iterator(elements(), rows_, pos);
    return {first, first + columns_};
  }

  /// Returns a pointer to the first element.
  data* elements();

  /// Returns a pointer to the first element.
  const data* elements() const {
    // We restore the const when returning from this member function.
    return const_cast<matrix_table_slice*>(this)->elements();
  }

  // -- memory management ------------------------------------------------------

  void request_deletion(bool) const noexcept override {
    // This object was allocated using `malloc`. Hence, we need to call `free`
    // instead of `delete` here.<commit_msg>Adhere to Doxygen style<commit_after>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include <cstdlib>
#include <memory>
#include <new>
#include <type_traits>

#include <caf/deserializer.hpp>
#include <caf/serializer.hpp>

#include "vast/data.hpp"
#include "vast/detail/range.hpp"
#include "vast/policy/column_major.hpp"
#include "vast/policy/row_major.hpp"
#include "vast/table_slice.hpp"
#include "vast/value_index.hpp"
#include "vast/view.hpp"

namespace vast {

/// An implementation of `table_slice` that keeps all entries in a
/// two-dimensional matrix, allocated in a single chunk of memory. As a
/// consequence, this table slice cannot grow and users have to provide the
/// maximum size upfront.
template <class LayoutPolicy>
class matrix_table_slice final : public table_slice {
public:
  // -- constants --------------------------------------------------------------

  static constexpr auto class_id = LayoutPolicy::class_id;

  // -- member types -----------------------------------------------------------

  /// Base type.
  using super = table_slice;

  /// Unsigned integer type.
  using size_type = super::size_type;

  /// Iterator over stored elements in unspecified order.
  using iterator = data*;

  /// Iterator over stored elements in unspecified order.
  using const_iterator = const data*;

  /// Iterator over stored elements in column-first order.
  using column_iterator = typename LayoutPolicy::column_iterator;

  /// Iterator over stored elements in column-first order.
  using const_column_iterator = typename LayoutPolicy::const_column_iterator;

  // -- constructors, destructors, and assignment operators --------------------

  ~matrix_table_slice() {
    // The element blocks gets allocated alongside this object. Hence, we need
    // to destroy our elements manually.
    auto first = elements();
    auto last = elements() + rows_ + columns_;
    for (auto i = first; i != last; ++i)
      i->~data();
  }

  /// @warning leaves all elements uninitialized.
  static matrix_table_slice* make_uninitialized(record_type layout,
                                                size_t rows);

  static matrix_table_slice* make(record_type layout, size_t rows) {
    auto ptr = make_uninitialized(std::move(layout), rows);
    std::uninitialized_default_construct(ptr->begin(), ptr->end());
    return ptr;
  }

  // -- properties -------------------------------------------------------------

  matrix_table_slice* copy() const override {
    auto ptr = make_uninitialized(this->layout(), rows_);
    std::uninitialized_copy(begin(), end(), ptr->begin());
    return ptr;
  }

  caf::error serialize(caf::serializer& sink) const override {
    for (auto i = begin(); i != end(); ++i)
      if (auto err = sink(*i))
        return err;
    return caf::none;
  }

  caf::error deserialize(caf::deserializer& source) override {
    for (auto i = begin(); i != end(); ++i)
      if (auto err = source(*i))
        return err;
    return caf::none;
  }

  void apply_column(size_type col, value_index& idx) const override {
    auto row = offset();
    for (auto& x : column(col))
      idx.append(make_view(x), row++);
  }

  caf::atom_value implementation_id() const noexcept override {
    return class_id;
  }

  data_view at(size_type row, size_type col) const override {
    auto ptr = elements();
    return make_view(ptr[LayoutPolicy::index_of(rows_, columns_, row, col)]);
  }

  iterator begin() {
    return elements();
  }

  iterator end() {
    return begin() + rows_ * columns_;
  }

  const_iterator begin() const {
    return elements();
  }

  const_iterator end() const {
    return begin() + rows_ * columns_;
  }

  /// @returns the range representing the column at position `pos`.
  detail::iterator_range<column_iterator> column(size_type pos) {
    auto first = LayoutPolicy::make_column_iterator(elements(), rows_, pos);
    return {first, first + columns_};
  }

  /// @returns the range representing the column at position `pos`.
  detail::iterator_range<const_column_iterator> column(size_type pos) const {
    auto first = LayoutPolicy::make_column_iterator(elements(), rows_, pos);
    return {first, first + columns_};
  }

  /// @returns a pointer to the first element.
  data* elements();

  /// @returns a pointer to the first element.
  const data* elements() const {
    // We restore the const when returning from this member function.
    return const_cast<matrix_table_slice*>(this)->elements();
  }

  // -- memory management ------------------------------------------------------

  void request_deletion(bool) const noexcept override {
    // This object was allocated using `malloc`. Hence, we need to call `free`
    // instead of `delete` here.
{'fraction_non_alphanumeric': 0.17640807651434645, 'fraction_numerical': 0.0, 'mean_word_length': 2.2962638645650904, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5306639', 'n_tokens_mistral': 2992, 'n_tokens_neox': 2884, 'n_words': 942}