/*
 * 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.
 */

/*-------------------------------------------------------------------------
 *
 * asetdirect.c
 *    A specialized implementation of the abstract MemoryContext type,
 *    which allocates directly from malloc() and does not support pfree().
 *
 * Portions Copyright (c) 2007-2008, Greenplum inc
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "utils/memutils.h"

#include "cdb/cdbptrbuf.h"              /* CdbPtrBuf */

/* Define this to detail debug alloc information */
/* #define HAVE_ALLOCINFO */


#ifdef CDB_PALLOC_CALLER_ID
#define CDB_MCXT_WHERE(context) (context)->callerFile, (context)->callerLine
#else
#define CDB_MCXT_WHERE(context) __FILE__, __LINE__
#endif


/*
 * AsetDirectContext
 */
typedef struct AsetDirectContext
{
    MemoryContextData   header;         /* standard memory-context fields */
    Size                size_total;     /* total size of all allocated areas */
    unsigned            narea_total;    /* number of allocated areas */
    CdbPtrBuf           areas;          /* collection of allocated area ptrs */

    /* variably-sized array, must be last */
    CdbPtrBuf_Ptr       areaspace[10];
} AsetDirectContext;

#define ASETDIRECTCONTEXT_BYTES(nareaspace) \
            (MAXALIGN(SIZEOF_VARSTRUCT(nareaspace, AsetDirectContext, areaspace)))


/*
 * These functions implement the MemoryContext API for AsetDirect contexts.
 */
static void *AsetDirectAlloc(MemoryContext context, Size size);
static void AsetDirectInit(MemoryContext context);
static void AsetDirectReset(MemoryContext context);
static void AsetDirectDelete(MemoryContext context);
static bool AsetDirectIsEmpty(MemoryContext context);
static void AsetDirectStats(MemoryContext context, uint64 *nBlocks, uint64 *nChunks,
		uint64 *currentAvailable, uint64 *allAllocated, uint64 *allFreed, uint64 *maxHeld);

#ifdef MEMORY_CONTEXT_CHECKING
static void AsetDirectCheck(MemoryContext context);
#endif

/*
 * This is the virtual function table for AsetDirect contexts.
 */
static MemoryContextMethods AsetDirectMethods = {
    AsetDirectAlloc,
    NULL,                               /* pfree */
    NULL,                               /* repalloc */
    AsetDirectInit,
    AsetDirectReset,
    AsetDirectDelete,
    NULL,                               /* GetChunkSpace */
    AsetDirectIsEmpty,
    AsetDirectStats,
#ifdef MEMORY_CONTEXT_CHECKING
    AsetDirectCheck
#endif
};


/* ----------
 * Debug macros
 * ----------
 */
#ifdef HAVE_ALLOCINFO
#define AllocAllocInfo(_cxt, _chunk) \
            fprintf(stderr, "AsetDirectAlloc: %s: %p, %d\n", \
				(_cxt)->header.name, (_chunk), (_cxt)->chunksize)
#else
#define AllocAllocInfo(_cxt, _chunk)
#endif


/*
 * Public routines
 */


/*
 * AsetDirectContextCreate
 *      Create a new AsetDirect context.
 *
 * parent: parent context, or NULL if top-level context
 * name: name of context (for debugging --- string will be copied)
 */
MemoryContext
AsetDirectContextCreate(MemoryContext parent, const char *name)
{
    AsetDirectContext  *set;
    Size                namesize = MAXALIGN(strlen(name) + 1);
    Size                allocsize;
    Size                setsize;        /* #bytes to request for new context */
    int                 nareaspace;     /* num of slots in areaspace array */

    /*
     * Determine amount of memory to request for the AsetDirectContext struct.
     *
     * Assume the total allocation will be rounded up to a power of 2, and
     * will include the AsetDirectContext with variably sized 'areaspace' array
     * and the context 'name' string.  Size the 'areaspace' array to use up any
     * extra space in the expected allocation.
     */
    allocsize = 1 << ceil_log2_Size(MAXALIGN(sizeof(AsetDirectContext)) + namesize);
    nareaspace = VARELEMENTS_TO_FIT(allocsize - namesize, AsetDirectContext, areaspace);
    setsize = ASETDIRECTCONTEXT_BYTES(nareaspace);

    /*
     * Create the new memory context and hook up to parent context.
     */
    set = (AsetDirectContext *)MemoryContextCreate(T_AsetDirectContext,
                                                   setsize,
                                                   &AsetDirectMethods,
                                                   parent,
                                                   name);

    /*
     * Initialize empty collection of ptrs to allocated areas.
     */
    CdbPtrBuf_Init(&set->areas,
                   set->areaspace,
                   nareaspace,
                   50,                      /* num_cells_expand */
                   set->header.parent);
    return (MemoryContext)set;
}                               /* AsetDirectContextCreate */


/*
 * AsetDirectInit
 *      Context-type-specific initialization routine.
 *
 * This is called by MemoryContextCreate() after setting up the
 * generic MemoryContext fields and before linking the new context
 * into the context tree.  We must do whatever is needed to make the
 * new context minimally valid for deletion.  We must *not* risk
 * failure --- thus, for example, allocating more memory is not cool.
 * (AsetDirectContextCreate can allocate memory when it gets control
 * back, however.)
 */
static void
AsetDirectInit(MemoryContext context)
{
	/*
	 * Since MemoryContextCreate already zeroed the context node, we don't
	 * have to do anything here: it's already OK.
	 */
}                               /* AsetDirectInit */


/*
 * AsetDirectReset
 *      Frees all memory which is allocated in the given set.
 */
static void
AsetDirectReset(MemoryContext context)
{
    AsetDirectContext  *set = (AsetDirectContext *)context;
    CdbPtrBuf_Iterator  it;
    CdbPtrBuf_Ptr      *pp;
    CdbPtrBuf_Ptr       p;

    Assert(set && IsA(set, AsetDirectContext));
    Assert(CdbPtrBuf_IsOk(&set->areas));

    /* Free allocated areas. */
    CdbPtrBuf_Iterator_Init(&it, &set->areas);
    while (NULL != (pp = CdbPtrBuf_Iterator_NextCell(&it)))
    {
        p = *pp;
        *pp = NULL;
        if (p)
        {
#ifdef CLOBBER_FREED_MEMORY
            /* Wipe first few bytes of freed memory for debugging purposes */
            memset(p, 0x7F, MAXALIGN(1));   /* don't know actual size of area */
#endif
            free(p);
        }
    }

    /* Empty the 'areas' collection. */
    CdbPtrBuf_Reset(&set->areas);

    /* Update statistics. */
    MemoryContextNoteFree(&set->header, set->size_total);
    set->narea_total = 0;
    set->size_total = 0;
}                               /* AsetDirectReset */


/*
 * AsetDirectDelete
 *      Frees all memory which is allocated in the given set,
 *      in preparation for deletion of the set.
 *
 * Unlike AsetDirectReset, this *must* free all resources of the set.
 * But note we are not responsible for deleting the context node itself.
 */
static void
AsetDirectDelete(MemoryContext context)
{
    AsetDirectReset(context);
}                               /* AsetDirectDelete */


/*
 * AsetDirectAlloc
 *      Returns pointer to allocated memory of given size; memory is added
 *      to the set.
 */
static void *
AsetDirectAlloc(MemoryContext context, Size size)
{
    AsetDirectContext  *set = (AsetDirectContext *)context;
    CdbPtrBuf_Ptr      *pp;

    Assert(set && IsA(set, AsetDirectContext));

    if (size < MAXALIGN(1))
        size = MAXALIGN(1);

    /* Obtain a slot in 'areas' collection to point to the new allocation. */
    pp = CdbPtrBuf_Append(&set->areas, NULL);

    /* Allocate the memory. */
    *pp = malloc(size);
    if (!*pp)
        MemoryContextError(ERRCODE_OUT_OF_MEMORY,
                           &set->header, CDB_MCXT_WHERE(&set->header),
                           "Out of memory.  Failed on request of size %lu bytes.",
                           (unsigned long)size);

    /* Update statistics. */
    set->size_total += size;
    set->narea_total++;
    MemoryContextNoteAlloc(&set->header, size);
    AllocAllocInfo(set, chunk);
    return *pp;
}                               /* AsetDirectAlloc */


/*
 * AsetDirectIsEmpty
 *      Is an allocset empty of any allocated space?
 */
static bool
AsetDirectIsEmpty(MemoryContext context)
{
    AsetDirectContext  *set = (AsetDirectContext *)context;

    return set->narea_total == 0;
}                               /* AsetDirectIsEmpty */

/*
 * AsetDirectStats
 *		Returns stats about memory consumption of an AsetDirectContext.
 *
 *	Input parameters:
 *		context: the context of interest
 *
 *	Output parameters:
 *		nBlocks: number of blocks in the context
 *		nChunks: number of chunks in the context
 *
 *		currentAvailable: free space across all blocks
 *
 *		allAllocated: total bytes allocated during lifetime (including
 *		blocks that was dropped later on, e.g., freeing a large chunk
 *		in an exclusive block would drop the block)
 *
 *		allFreed: total bytes that was freed during lifetime
 *		maxHeld: maximum bytes held during lifetime
 */
static void
AsetDirectStats(MemoryContext context, uint64 *nBlocks, uint64 *nChunks,
		uint64 *currentAvailable, uint64 *allAllocated, uint64 *allFreed, uint64 *maxHeld)
{
    AsetDirectContext  *set = (AsetDirectContext *)context;

    Assert(set && IsA(set, AsetDirectContext));

    *nBlocks = 0;
    *nChunks = set->narea_total;
    *currentAvailable = 0;
    *allAllocated = set->header.allBytesAlloc;
    *allFreed = set->header.allBytesFreed;
    *maxHeld = set->header.maxBytesHeld;
}


#ifdef MEMORY_CONTEXT_CHECKING
/*
 * AsetDirectCheck
 *      Walk through chunks and check consistency of memory.
 *
 * NOTE: report errors as WARNING, *not* ERROR or FATAL.  Otherwise you'll
 * find yourself in an infinite loop when trouble occurs, because this
 * routine will be entered again when elog cleanup tries to release memory!
 */
static void
AsetDirectCheck(MemoryContext context)
{
    AsetDirectContext  *set = (AsetDirectContext *)context;
    const char         *name = set->header.name;

    if (!IsA(set, AsetDirectContext))
        elog(WARNING, "problem in alloc set %s: type=%d",
             name, set->header.type);

    else if (!CdbPtrBuf_IsOk(&set->areas))
        elog(WARNING, "problem in alloc set %s: CdbPtrBuf error",
             name);

    else if (set->narea_total < 0 ||
             set->narea_total > CdbPtrBuf_Length(&set->areas))
        elog(WARNING, "problem in alloc set %s: narea=%d",
             name, set->narea_total);

}                               /* AsetDirectCheck */
#endif   /* MEMORY_CONTEXT_CHECKING */
