/* ----------------------------------------------------------------------- *//**
 *
 * @file Allocator_impl.hpp
 *
 *//* ----------------------------------------------------------------------- */

#ifndef MADLIB_POSTGRES_ALLOCATOR_IMPL_HPP
#define MADLIB_POSTGRES_ALLOCATOR_IMPL_HPP

namespace madlib {

namespace dbconnector {

namespace postgres {

/**
 * @brief Construct an empty postgres array of the given size.
 *
 * This calls allocate() to allocate a block of memory and then initializes
 * PostgreSQL meta information.
 *
 * @note
 *     There is a template-overloaded version with defaults
 *     <tt>MC = dbal::FunctionContext</tt>, <tt>ZM = dbal::DoZero</tt>,
 *     <tt>F = dbal::ThrowBadAlloc</tt>
 */
template <typename T, std::size_t Dimensions, dbal::MemoryContext MC,
    dbal::ZeroMemory ZM, dbal::OnMemoryAllocationFailure F>
inline
MutableArrayHandle<T>
Allocator::internalAllocateArray(
    const std::array<std::size_t, Dimensions>& inNumElements) const {

    std::size_t numElements = Dimensions ? 1 : 0;
    for (std::size_t i = 0; i < Dimensions; ++i)
        numElements *= inNumElements[i];

    /*
     * Check that the size will not exceed addressable memory. Therefore, the
     * following precondition has to hold:
     * ((std::numeric_limits<std::size_t>::max()
     *     - ARR_OVERHEAD_NONULLS(Dimensions)) / inElementSize >= numElements)
     */
    if ((std::numeric_limits<std::size_t>::max()
        - ARR_OVERHEAD_NONULLS(Dimensions)) / sizeof(T) < numElements)
        throw std::bad_alloc();

    std::size_t size = sizeof(T) * numElements
        + ARR_OVERHEAD_NONULLS(Dimensions);
    ArrayType *array;

    // Note: Except for the allocate call, the following statements do not call
    // into the PostgreSQL backend. We are only using macros here.

    // PostgreSQL requires that all memory is overwritten with zeros. So
    // we ingore ZM here
    array = static_cast<ArrayType*>(allocate<MC, dbal::DoZero, F>(size));

    SET_VARSIZE(array, size);
    array->ndim = Dimensions;
    array->dataoffset = 0;
    array->elemtype = TypeTraits<T>::oid;
    for (std::size_t i = 0; i < Dimensions; ++i) {
        ARR_DIMS(array)[i] = static_cast<int>(inNumElements[i]);
        ARR_LBOUND(array)[i] = 1;
    }

    return MutableArrayHandle<T>(array);
}

#define MADLIB_ALLOCATE_ARRAY_DEF(z, n, _ignored) \
    template <typename T> \
    inline \
    MutableArrayHandle<T> \
    Allocator::allocateArray( \
        BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(n), std::size_t inDim) \
    ) const { \
        std::array<std::size_t, BOOST_PP_INC(n)> numElements = {{ \
            BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(n), inDim) \
        }}; \
        return internalAllocateArray<T, BOOST_PP_INC(n), \
            dbal::FunctionContext, dbal::DoZero, dbal::ThrowBadAlloc> \
            (numElements); \
    } \
    \
    template <typename T, dbal::MemoryContext MC, \
        dbal::ZeroMemory ZM, dbal::OnMemoryAllocationFailure F> \
    inline \
    MutableArrayHandle<T> \
    Allocator::allocateArray( \
        BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(n), std::size_t inDim) \
    ) const { \
        std::array<std::size_t, BOOST_PP_INC(n)> numElements = {{ \
            BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(n), inDim) \
        }}; \
        return internalAllocateArray<T, BOOST_PP_INC(n), MC, ZM, F> \
        (numElements); \
    }
BOOST_PP_REPEAT(MADLIB_MAX_ARRAY_DIMS, MADLIB_ALLOCATE_ARRAY_DEF,
    0 /* ignored */)
#undef MADLIB_ALLOCATE_ARRAY_DEF

/**
 * @brief Construct a byte string of the given size
 */
template <dbal::MemoryContext MC, dbal::ZeroMemory ZM,
    dbal::OnMemoryAllocationFailure F>
inline
MutableByteString
Allocator::allocateByteString(std::size_t inSize) const {
    bytea* byteString = static_cast<bytea*>(
        allocate<MC, dbal::DoZero, F>(ByteString::kEffectiveHeaderSize + inSize)
    );
    SET_VARSIZE(byteString, ByteString::kEffectiveHeaderSize + inSize);
    return byteString;
}

/**
 * @brief Allocate a block of memory
 *
 * @return The address of a 16-byte aligned block of memory large enough to hold
 *     \c inSize bytes. On all supported platforms, 16-byte alignment is enough
 *     for any arbitrary operation.
 */
template <dbal::MemoryContext MC, dbal::ZeroMemory ZM,
    dbal::OnMemoryAllocationFailure F>
inline
void *
Allocator::allocate(size_t inSize) const {
    return internalAllocate<MC, ZM, F, NewAllocation>(NULL, inSize);
}

/**
 * @brief Change the size of a block of memory previously allocated with
 *     Allocator allocation functions
 *
 * There is no guerantee that the returned pointer is the same as \c inPtr.
 *
 * @param inPtr Pointer to a memory block previously allocated with allocate or
 *     reallocate.
 * @param inSize Requested size for the reallocated memory block
 *
 * @return The address of a 16-byte aligned block of memory large enough to hold
 *     \c inSize bytes. On all supported platforms, 16-byte alignment is enough
 *     for any arbitrary operation.
 */
template <dbal::MemoryContext MC, dbal::ZeroMemory ZM,
    dbal::OnMemoryAllocationFailure F>
inline
void *
Allocator::reallocate(void *inPtr, const size_t inSize) const {
    return internalAllocate<MC, ZM, F, Reallocation>(inPtr, inSize);
}


/**
 * @brief Free a block of memory previously allocated with
 *     Allocator allocation functions
 *
 * @internal
 *     This function uses the PostgreSQL pfree() macro. This calls
 *     MemoryContextFreeImpl, which again calls, by default, AllocSetFree() from
 *     utils/mmgr/aset.c.
 *
 * We must not throw errors, so we are essentially ignoring all errors.
 * This function is also called by operator delete(),
 * which must not throw *any* exceptions.
 *
 * @param inPtr Pointer to a memory block previously allocated with allocate,
 *     reallocate or allocateArray. If a null pointer is passed as argument, no
 *     action occurs. (std::free has the same behavior.)
 *
 * @see See also the notes for PGAllocator::allocate(const size_t) and
 *      PGAllocator::allocate(const size_t, const std::nothrow_t&)
 */
template <dbal::MemoryContext MC>
inline
void
Allocator::free(void *inPtr) const {
    if (inPtr == NULL)
        return;

    /*
     * See allocate(const size_t, const std::nothrow_t&) why we disable
     * processing of interrupts.
     */
    HOLD_INTERRUPTS();
    PG_TRY(); {
        pfree(unaligned(inPtr));
    } PG_CATCH(); {
        FlushErrorState();
    } PG_END_TRY();
    RESUME_INTERRUPTS();
}

/**
 * @brief Thin wrapper around \c palloc() that returns a 16-byte-aligned
 *     pointer.
 *
 * @internal
 *     This function uses the PostgreSQL palloc() and palloc0() macros. They
 *     call MemoryContextAllocImpl() or MemoryContextAllocZeroImpl(),
 *     respectively, which then call, by default, AllocSetAlloc() from
 *     utils/mmgr/aset.c.
 *
 * Unless <tt>MAXIMUM_ALIGNOF >= 16</tt>, we waste 16 additional bytes of
 * memory. The call to \c palloc() might throw a PostgreSQL exception. Thus,
 * this function should only be used inside a \c PG_TRY() block.
 */
template <dbal::ZeroMemory ZM>
inline
void *
Allocator::internalPalloc(size_t inSize) const {
#if MAXIMUM_ALIGNOF >= 16
    return (ZM == dbal::DoZero) ? palloc0(inSize) : palloc(inSize);
#else
    if (inSize > std::numeric_limits<size_t>::max() - 16)
        return NULL;

    /* Precondition: inSize <= std::numeric_limits<size_t>::max() - 16 */
    const size_t size = inSize + 16;
    void *raw = (ZM == dbal::DoZero) ? palloc0(size) : palloc(size);
    return makeAligned(raw);
#endif
}

/**
 * @brief Thin wrapper around \c repalloc() that returns a 16-byte-aligned
 *     pointer.
 *
 * @tparam ZM Initialize memory block by overwriting with zeros?
 *
 * @internal
 *     This function uses the PostgreSQL repalloc() macro. This calls
 *     MemoryContextReallocImpl, which again calls, by default,
 *     AllocSetRealloc() from utils/mmgr/aset.c.
 *
 * Unless <tt>MAXIMUM_ALIGNOF >= 16</tt>, we waste 16 additional bytes of
 * memory. The call to \c repalloc() might throw a PostgreSQL exception. Thus,
 * this function should only be used inside a \c PG_TRY() block.
 */
template <dbal::ZeroMemory ZM>
inline
void *
Allocator::internalRePalloc(void *inPtr, size_t inSize) const {
#if MAXIMUM_ALIGNOF >= 16
    return repalloc(inPtr, inSize);
#else
    if (inSize > std::numeric_limits<size_t>::max() - 16) {
        pfree(unaligned(inPtr));
        return NULL;
    }

    /* Precondition: inSize <= std::numeric_limits<size_t>::max() - 16 */
    const size_t size = inSize + 16;
    void *raw = repalloc(unaligned(inPtr), size);

    if (ZM == dbal::DoZero) {
        std::fill(
            static_cast<char*>(raw),
            static_cast<char*>(raw) + inSize, 0);
    }

    return makeAligned(raw);
#endif
}

/**
 * @internal
 * @brief Return next 16-byte boundary after inPtr and store inPtr in word
 *     immediately before that
 */
inline
void *
Allocator::makeAligned(void *inPtr) const {
    if (inPtr == NULL) return NULL;

    /*
     * Precondition: reinterprete_cast<size_t>(raw) % sizeof(void**) == 0,
     * i.e., the memory returned by palloc is at least aligned on word size
     * boundaries. That ensures that the word immediately preceding raw belongs
     * to us an can be written to safely.
     */
    void *aligned = reinterpret_cast<void*>(
        (reinterpret_cast<uintptr_t>(inPtr) & ~(uintptr_t(15))) + 16);
    *(reinterpret_cast<void**>(aligned) - 1) = inPtr;
    return aligned;
}

/**
 * @internal
 * @brief Return the address of memory block that corresponds to the given
 *     16-byte aligned address
 *
 * Unless <tt>MAXIMUM_ALIGNOF >= 16</tt>, we free the block of memory pointed to
 * by the word immediately in front of the memory pointed to by \c inPtr.
 */
inline
void *
Allocator::unaligned(void *inPtr) const {
#if MAXIMUM_ALIGNOF >= 16
    return inPtr;
#else
    return (*(reinterpret_cast<void**>(inPtr) - 1));
#endif
}

/**
 * @brief Allocate memory in our PostgreSQL memory context. Throws on fail.
 *
 * @tparam MC Which memory context to allocate in?
 * @tparam ZM Initialize memory block by overwriting with zeros?
 * @tparam F What to do in case of failure?
 * @tparam R Do a reallication or a new allocation?
 *
 * If <tt>F == ThrowBadAlloc</tt>: In case allocation fails, throw an exception.
 * At the boundary of the C++ layer, another PostgreSQL error will be raised
 * (i.e., there will be at least two errors on the PostgreSQL error handling
 * stack).
 *
 * If <tt>F == ReturnNULL</tt>: In case allocation fails, do not throw an
 * exception. ALso, make sure we do not leave in an error state. Instead, we
 * just return NULL.
 *
 * We will hold back interrupts while in this function because we do not want
 * to flush the postgres error state unless it is related to memory allocation.
 * (We have to flush the error state because we cannot throw exceptions within
 * allocate).
 *
 * Interrupts/Signals are only processed whenever the CHECK_FOR_INTERRUPTS()
 * macro is called (see miscadmin.h). Some PostgreSQL function implicitly call
 * this macro (a notable example being ereport -- the rationale here is that
 * the user should be able to abort queries that produce lots of output).
 * For the actual processing, see ProcessInterrupts() in tcop/postgres.c.
 * All aborting is done through the ereport mechanism.
 *
 * By default, PostgreSQL's memory allocation happens in AllocSetAlloc from
 * utils/mmgr/aset.c.
 *
 * @see PGInterface for information on necessary precautions when writing
 *      PostgreSQL plug-in code in C++.
 *
 * @exception std::bad_alloc if the allocation fails and
 *            <tt>F == ThrowBadAlloc</tt>
 */
template <
    dbal::MemoryContext MC,
    dbal::ZeroMemory ZM,
    dbal::OnMemoryAllocationFailure F,
    Allocator::ReallocateMemory R>
inline
void *
Allocator::internalAllocate(void *inPtr, const size_t inSize) const {
    // Avoid warning that inPtr is not used if R == NewAllocation
    (void) inPtr;

    void *ptr;
    bool errorOccurred = false;

    if (F == dbal::ReturnNULL) {
        /*
         * HOLD_INTERRUPTS() and RESUME_INTERRUPTS() only change the value of a
         * global variable but have no other side effects. In particular, they
         * do not call CHECK_INTERRUPTS(). Hence, we are save to use these
         * macros outside of a PG_TRY() block.
         */
        HOLD_INTERRUPTS();
    }

    PG_TRY(); {
        /*
         * We used to respect the request for MC == dbal::AggregateContext here,
         * but current PostgreSQL/Greenplum versions do not take any advantage
         * of transition states allocated in the aggregate context anyways.
         * They still copy the transition state, whenever the address of the
         * returned state is different from the address of the input state.
         *
         * Any other use of the aggregate context (say, auxiliary data/caches
         * for transition states) is not currently supported by the C++ AL.
         *
         * See also: MADLIB-606 (issue that triggered this code change).
         */
        ptr = R ? internalRePalloc<ZM>(inPtr, inSize)
                : internalPalloc<ZM>(inSize);
    } PG_CATCH(); {
        if (F == dbal::ReturnNULL) {
            /*
             * This cannot be due to an interrupt, so it's reasonably safe
             * to assume that the PG exception was a pure memory-allocation
             * issue. We ignore the error and flush the error state.
             * Flushing is necessary for leaving the error state (e.g., the memory
             * context is restored).
             */
            FlushErrorState();
            ptr = NULL;
        } else {
            /*
             * PostgreSQL error messages can be stacked. So, it doesn't hurt to add
             * our own message. After unwinding the C++ stack, the PostgreSQL
             * exception will be re-thrown into the PostgreSQL C code.
             *
             * Throwing C++ exceptions inside a PG_CATCH block is not problematic
             * per se, but it is good practise to keep the exception mechanisms clearly
             * separated.
             */

            errorOccurred = true;
        }
    } PG_END_TRY();

    if (F == dbal::ReturnNULL) {
        RESUME_INTERRUPTS();
    }

    if (errorOccurred || !ptr)
        // We do not want to interleave PG exceptions and C++ exceptions.
        throw std::bad_alloc();

    return ptr;
}

/**
 * @brief Get the default allocator
 */
inline
Allocator&
defaultAllocator() {
    static Allocator sDefaultAllocator;
    return sDefaultAllocator;
}

} // namespace postgres

} // namespace dbconnector

} // namespace madlib

#endif // defined(MADLIB_POSTGRES_ALLOCATOR_IMPL_HPP)
