//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Data structures for sorting routines.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_STDLIB_QSORT_DATA_H
#define LLVM_LIBC_SRC_STDLIB_QSORT_DATA_H

#include "hdr/stdint_proxy.h"
#include "src/__support/CPP/cstddef.h"
#include "src/__support/CPP/utility/swap.h"
#include "src/__support/macros/config.h"
#include "src/string/memory_utils/inline_memcpy.h"

namespace LIBC_NAMESPACE_DECL {
namespace internal {

class ArrayGenericSize {
  cpp::byte *array_base;
  size_t array_len;
  size_t elem_size;

  LIBC_INLINE cpp::byte *get_internal(size_t i) const {
    return array_base + (i * elem_size);
  }

public:
  LIBC_INLINE ArrayGenericSize(void *a, size_t s, size_t e)
      : array_base(reinterpret_cast<cpp::byte *>(a)), array_len(s),
        elem_size(e) {}

  static constexpr bool has_fixed_size() { return false; }

  LIBC_INLINE void *get(size_t i) const { return get_internal(i); }

  LIBC_INLINE void swap(size_t i, size_t j) const {
    // It's possible to use 8 byte blocks with `uint64_t`, but that
    // generates more machine code as the remainder loop gets
    // unrolled, plus 4 byte operations are more likely to be
    // efficient on a wider variety of hardware. On x86 LLVM tends
    // to unroll the block loop again into 2 16 byte swaps per
    // iteration which is another reason that 4 byte blocks yields
    // good performance even for big types.
    using block_t = uint32_t;
    constexpr size_t BLOCK_SIZE = sizeof(block_t);

    alignas(block_t) cpp::byte tmp_block[BLOCK_SIZE];

    cpp::byte *elem_i = get_internal(i);
    cpp::byte *elem_j = get_internal(j);

    const size_t elem_size_rem = elem_size % BLOCK_SIZE;
    const cpp::byte *elem_i_block_end = elem_i + (elem_size - elem_size_rem);

    while (elem_i != elem_i_block_end) {
      inline_memcpy(tmp_block, elem_i, BLOCK_SIZE);
      inline_memcpy(elem_i, elem_j, BLOCK_SIZE);
      inline_memcpy(elem_j, tmp_block, BLOCK_SIZE);

      elem_i += BLOCK_SIZE;
      elem_j += BLOCK_SIZE;
    }

    for (size_t n = 0; n < elem_size_rem; ++n)
      cpp::swap(elem_i[n], elem_j[n]);
  }

  LIBC_INLINE size_t len() const { return array_len; }

  // Make an Array starting at index |i| and length |s|.
  LIBC_INLINE ArrayGenericSize make_array(size_t i, size_t s) const {
    return ArrayGenericSize(get_internal(i), s, elem_size);
  }

  // Reset this Array to point at a different interval of the same
  // items starting at index |i|.
  LIBC_INLINE void reset_bounds(size_t i, size_t s) {
    array_base = get_internal(i);
    array_len = s;
  }
};

// Having a specialized Array type for sorting that knows at
// compile-time what the size of the element is, allows for much more
// efficient swapping and for cheaper offset calculations.
template <size_t ELEM_SIZE> class ArrayFixedSize {
  cpp::byte *array_base;
  size_t array_len;

  LIBC_INLINE cpp::byte *get_internal(size_t i) const {
    return array_base + (i * ELEM_SIZE);
  }

public:
  LIBC_INLINE ArrayFixedSize(void *a, size_t s)
      : array_base(reinterpret_cast<cpp::byte *>(a)), array_len(s) {}

  // Beware this function is used a heuristic for cheap to swap types, so
  // instantiating `ArrayFixedSize` with `ELEM_SIZE > 100` is probably a bad
  // idea perf wise.
  static constexpr bool has_fixed_size() { return true; }

  LIBC_INLINE void *get(size_t i) const { return get_internal(i); }

  LIBC_INLINE void swap(size_t i, size_t j) const {
    alignas(32) cpp::byte tmp[ELEM_SIZE];

    cpp::byte *elem_i = get_internal(i);
    cpp::byte *elem_j = get_internal(j);

    inline_memcpy(tmp, elem_i, ELEM_SIZE);
    __builtin_memmove(elem_i, elem_j, ELEM_SIZE);
    inline_memcpy(elem_j, tmp, ELEM_SIZE);
  }

  LIBC_INLINE size_t len() const { return array_len; }

  // Make an Array starting at index |i| and length |s|.
  LIBC_INLINE ArrayFixedSize<ELEM_SIZE> make_array(size_t i, size_t s) const {
    return ArrayFixedSize<ELEM_SIZE>(get_internal(i), s);
  }

  // Reset this Array to point at a different interval of the same
  // items starting at index |i|.
  LIBC_INLINE void reset_bounds(size_t i, size_t s) {
    array_base = get_internal(i);
    array_len = s;
  }
};

} // namespace internal
} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STDLIB_QSORT_DATA_H
