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

/*-------------------------------------------------------------------------
 *
 * cdbcellbuf.h
 *    a container for small items of constant size
 *
 *-------------------------------------------------------------------------
 */
#ifndef CDBCELLBUF_H
#define CDBCELLBUF_H

#include "cdb/cdbpublic.h"              /* CdbCellBuf */


/* Private helper functions needed by inline functions below... */
void *CdbCellBuf_AppendMore(CdbCellBuf *cellbuf);
void *CdbCellBuf_PopMore(CdbCellBuf *cellbuf);
void *CdbCellBuf_LastCellHelper(CdbCellBuf *cellbuf);


/*-------------------------------------------------------------------------
 *                           CdbCellBuf_Iterator
 *-------------------------------------------------------------------------
 * For iterating over the cells of a CdbCellBuf.
 */
typedef struct CdbCellBuf_Iterator
{
    char            *cnext;             /* next cell */
    char            *cend;              /* end of last cell of current bunch */
    CdbCellBuf      *cellbuf;
    char            *cbeg;              /* first cell of current bunch */
    long             begoff;            /* total size (bytes) of all cells in
                                         *   bunches preceding current bunch */
} CdbCellBuf_Iterator;

/* Private helper functions needed by inline functions below... */
char *CdbCellBuf_Iterator_NextCellHelper(CdbCellBuf_Iterator *it);
char *CdbCellBuf_Iterator_PrevCellHelper(CdbCellBuf_Iterator *it);
char *CdbCellBuf_Iterator_CellAtHelper(CdbCellBuf_Iterator *it, long relCellOff);
void CdbCellBuf_Iterator_SetPosHelper(CdbCellBuf_Iterator *it, long nextCellOff);


/*-------------------------------------------------------------------------
 *                            CdbCellBuf_Bumper
 *-------------------------------------------------------------------------
 * Each dynamically allocated expansion bunch of cells begins and ends with
 * a bumper.  At the beginning is a prefix bumper whose 'link' field points
 * to the prefix bumper of the previous expansion bunch (or NULL in the first
 * expansion bunch).  At the end of the bunch is a suffix bumper whose 'link'
 * field points to the prefix bumper of the next expansion bunch.  The suffix
 * bumper of the last expansion bunch is uninitialized.  Between the prefix
 * and suffix bumper are cells in the quantity 'cellbuf->num_cells_expand'.
 */
typedef struct CdbCellBuf_Bumper
{
    CdbCellBuf                 *cellbuf;    /* owner of bunch */
    struct CdbCellBuf_Bumper   *link;       /* prefix: -> prev bunch pfx or NULL.
                                             * suffix: -> prefix of next bunch.
                                             */
} CdbCellBuf_Bumper;
#define CDBCELLBUF_BUMPER_BYTES  (MAXALIGN(sizeof(CdbCellBuf_Bumper)))



/*-------------------------------------------------------------------------
 *                    Initialize/Reset caller's CdbCellBuf
 *-------------------------------------------------------------------------
 */

/*
 * CdbCellBuf_InitEasy
 *
 * Initialize caller's CdbCellBuf struct (easy-to-call version).
 *
 * 'cellbuf' is the area to be initialized as a CdbCellBuf.
 * 'cellbytes' is the size of each cell.
 */
void
CdbCellBuf_InitEasy(CdbCellBuf *cellbuf, Size cellbytes);

/*
 * CdbCellBuf_Init
 *
 * Initialize caller's CdbCellBuf struct.
 *
 * 'cellbuf' is the area to be initialized as a CdbCellBuf.
 * 'cellbytes' is the size of each cell.
 * 'initial_cell_area' is an optional memory area, properly aligned, where
 *      the first few cells can be stored.  It must be nearby the CdbCellBuf
 *      itself, typically in the same struct or local variable stack frame.
 *      This allows a small number of cells to be managed with good locality
 *      and no palloc/pfree.  If NULL, cell memory is allocated from 'context'
 *      when needed.
 * 'num_initial_cells' is the exact number of cells in the initial_cell_area.
 * 'num_cells_expand' is the suggested number of cell slots to be allocated
 *      whenever additional memory is needed.  The actual number will be
 *      rounded to fully utilize a power-of-2 chunk.  However, no expansion
 *      is done if num_cells_expand is zero; instead, after the initial
 *      cells are exhausted an error is raised.
 * 'context' is the memory context from which to allocate space for
 *      additional cells when there is no more room in initial_cell_area.
 *      If NULL, the CurrentMemoryContext is used.
 */
void
CdbCellBuf_Init(CdbCellBuf     *cellbuf,
                size_t          cellbytes,
                void           *initial_cell_area,
                int             num_initial_cells,
                int             num_cells_expand,
                MemoryContext   context);

/*
 * CdbCellBuf_Reset
 *
 * Free memory held by a cellbuf.  Does not free the CdbCellBuf struct.
 *
 * Should be used to clean up cellbufs initialized by CdbCellBuf_Init()
 * or CdbCellBuf_InitEasy().  May be used to empty any cellbuf for reuse.
 *
 * (NB: An acceptable alternative for cleaning up would be to destroy or
 * reset the associated MemoryContext.)
 *
 * Iterators (CdbCellBuf_Iterator) become invalid when their cellbuf is
 * reset; afterward the caller should abandon or reinitialize them.
 */
void
CdbCellBuf_Reset(CdbCellBuf *cellbuf);

/*-------------------------------------------------------------------------
 *              Create/Destroy dynamically allocated CdbCellBuf
 *-------------------------------------------------------------------------
 */

/*
 * CdbCellBuf_Create
 *
 * Returns a newly allocated CdbCellBuf.
 *
 * 'cellbytes' is the size of each cell.
 * 'num_initial_cells' is the suggested number of cell slots to be created
 *      immediately following the CdbCellBuf.  This allows a small number
 *      of cells to be managed with good locality and no palloc/pfree.
 *      If NULL, all cells are stored in chunks allocated from 'context'.
 *      The actual number will be rounded up to minimize wasted space.
 * 'num_cells_expand' is the suggested number of cell slots to be allocated
 *      whenever additional memory is needed.  The actual number will be
 *      rounded to fully utilize a power-of-2 chunk.  However, no expansion
 *      is done if num_cells_expand is zero; instead, after the initial
 *      cells are exhausted an error is raised.
 * 'context' is the memory context from which the CdbCellBuf and cells are
 *      to be allocated.  If NULL, the CurrentMemoryContext is used.
 */
CdbCellBuf *
CdbCellBuf_Create(size_t          cellbytes,
                  int             num_initial_cells,
                  int             num_cells_expand,
                  MemoryContext   context);

/*
 * CdbCellBuf_Destroy
 *
 * Free a CdbCellBuf struct allocated by CdbCellBuf_Create().
 *
 * Do not use this to free a cellbuf allocated by CdbCellBuf_CreateWrap()
 * unless offsetof_cellbuf_in_struct == 0.
 *
 * NB: CdbCellBuf_Reset() can be used to free the memory owned by a cellbuf
 * without freeing the CdbCellBuf struct itself.  That is safe for all
 * cellbufs.
 *
 * NB: An acceptable alternative for cleaning up would be to destroy or
 * reset the associated MemoryContext.
 */
void
CdbCellBuf_Destroy(CdbCellBuf *cellbuf);

/*
 * CdbCellBuf_CreateWrap
 *
 * Returns zeroed, newly allocated memory for a structure of given size,
 * with a CdbCellBuf initialized at a given offset within the structure,
 * and followed by space for initial cells.
 *
 * 'sizeof_outer_struct' is the size of the struct in which the CdbCellBuf is
 *      embedded.
 * 'offsetof_cellbuf_in_struct' is the offset of the CdbCellBuf within that.
 * 'cellbytes' is the size of each cell.
 * 'num_initial_cells' is the suggested number of cell slots to be created
 *      immediately following the struct.  This allows a small number
 *      of cells to be managed with good locality and no palloc/pfree.
 *      If NULL, all cells are stored in chunks allocated from 'context'.
 *      The actual number will be rounded up to minimize wasted space.
 * 'num_cells_expand' is the suggested number of cell slots to be allocated
 *      whenever additional memory is needed.  The actual number will be
 *      rounded to fully utilize a power-of-2 chunk.  However, no expansion
 *      is done if num_cells_expand is zero; instead, after the initial
 *      cells are exhausted an error is raised.
 * 'context' is the memory context from which the CdbCellBuf and cells are
 *      to be allocated.  If NULL, the CurrentMemoryContext is used.
 */
void *
CdbCellBuf_CreateWrap(size_t        sizeof_outer_struct,
                      size_t        offsetof_cellbuf_in_struct,
                      size_t        cellbytes,
                      int           num_initial_cells,
                      int           num_cells_expand,
                      MemoryContext context);


/*-------------------------------------------------------------------------
 *                          Examine cellbuf state
 *-------------------------------------------------------------------------
 */

/*
 * CdbCellBuf_Context
 *
 * Returns the memory context used for allocating additional bunches of cells.
 */
static inline MemoryContext
CdbCellBuf_Context(const CdbCellBuf *cellbuf)
{
    return cellbuf->context;
}                               /* CdbCellBuf_Context */


/*
 * CdbCellBuf_IsEmpty
 *
 * Returns true if cellbuf is empty.
 */
static inline bool
CdbCellBuf_IsEmpty(const CdbCellBuf *cellbuf)
{
    return cellbuf->nfull_total == 0;
}                               /* CdbCellBuf_IsEmpty */


/*
 * CdbCellBuf_IsOk
 *
 * Returns true if the cellbuf passes a consistency check.
 *
 * 'cellbytes' must be the cell size which was given at initialization.
 */
bool
CdbCellBuf_IsOk(const CdbCellBuf *cellbuf, Size cellbytes);


/*
 * CdbCellBuf_Length
 *
 * Returns the number of cells in use.
 */
static inline long
CdbCellBuf_Length(const CdbCellBuf *cellbuf)
{
    return cellbuf->nfull_total;
}                               /* CdbCellBuf_Length */


/*
 * CdbCellBuf_FirstCell
 *
 * Returns a pointer to the first cell, or NULL if the cellbuf is empty.
 */
static inline void *
CdbCellBuf_FirstCell(CdbCellBuf *cellbuf)
{
    char   *firstcell = NULL;

    if (cellbuf->nearby_bunch_len > 0)
        firstcell = (char *)cellbuf + cellbuf->offset_nearby;
    else if (cellbuf->head)
    {
        Assert(cellbuf->head->cellbuf == cellbuf);
        firstcell = (char *)cellbuf->head + CDBCELLBUF_BUMPER_BYTES;
    }

    if (firstcell == cellbuf->cfree)
        firstcell = NULL;

    Assert((firstcell != NULL) == (cellbuf->nfull_total > 0));

    return firstcell;
}                               /* CdbCellBuf_FirstCell */


/*
 * CdbCellBuf_LastCell
 *
 * Returns a pointer to the last cell, or NULL if the cellbuf is empty.
 */
static inline void *
CdbCellBuf_LastCell(CdbCellBuf *cellbuf)
{
    char   *lastcell;

    if (cellbuf->cbeg < cellbuf->cfree)
    {
        Assert(cellbuf->cbeg + cellbuf->cellbytes <= cellbuf->cfree &&
               cellbuf->cfree <= cellbuf->cend);
        lastcell = cellbuf->cfree - cellbuf->cellbytes;
    }
    else if (cellbuf->nfull_total > 0)
        lastcell = CdbCellBuf_LastCellHelper(cellbuf);
    else
        lastcell = NULL;

    return lastcell;
}                               /* CdbCellBuf_LastCell */


/*-------------------------------------------------------------------------
 *                              Cell operations
 *-------------------------------------------------------------------------
 */

/*
 * CdbCellBuf_AppendCell
 *
 * Allocate a cell at tail of cellbuf.
 *
 * Returns pointer to the cell.  The cell has not been initialized.
 */
static inline void *
CdbCellBuf_AppendCell(CdbCellBuf *cellbuf)
{
    void   *cell;

    Assert(cellbuf &&
           cellbuf->cellbytes > 0);

    if (cellbuf->cfree < cellbuf->cend)
    {
        Assert(cellbuf->cbeg &&
               cellbuf->cbeg <= cellbuf->cfree &&
               cellbuf->cfree + cellbuf->cellbytes <= cellbuf->cend);

        cell = cellbuf->cfree;
        cellbuf->cfree += cellbuf->cellbytes;
    }
    else
        cell = CdbCellBuf_AppendMore(cellbuf);

    cellbuf->nfull_total++;
    return cell;
}                               /* CdbCellBuf_AppendCell */


/*
 * CdbCellBuf_PopCell
 *
 * Deallocate a cell at tail of cellbuf.
 *
 * Returns pointer to the cell, or NULL if cellbuf is empty.  The contents
 * of the popped cell remain valid until the next cell operation, or until
 * CdbCellBuf_Reset() or CdbCellBuf_Destroy().
 */
static inline void *
CdbCellBuf_PopCell(CdbCellBuf *cellbuf)
{
    void   *cell;

    Assert(cellbuf &&
           cellbuf->cellbytes > 0);

    if (cellbuf->cbeg < cellbuf->cfree)
    {
        Assert(cellbuf->cbeg &&
               cellbuf->cbeg + cellbuf->cellbytes <= cellbuf->cfree &&
               cellbuf->cfree <= cellbuf->cend);

        cell = cellbuf->cfree - cellbuf->cellbytes;
        cellbuf->cfree = cell;
        cellbuf->nfull_total--;
    }
    else if (cellbuf->nfull_total > 0)
        cell = CdbCellBuf_PopMore(cellbuf);
    else
        cell = NULL;

    return cell;
}                               /* CdbCellBuf_PopCell */


/*-------------------------------------------------------------------------
 *                            CdbCellBuf_Iterator
 *-------------------------------------------------------------------------
 */

/*
 * CdbCellBuf_Iterator_Init
 *
 * Initializes caller's CdbCellBuf_Iterator struct, positioning the iterator
 * before the first cell.
 *
 * It is ok to delete items (via CdbCellBuf_PopCell()) that are after the
 * iterator position.  However, deletion of an item that precedes the iterator
 * position can leave the iterator in an inconsistent state; you must take care
 * not to use that iterator any more after popping a preceding item.
 *
 * The following should not be called while iterating: CdbCellBuf_Reset(),
 * CdbCellBuf_Destroy().
 */
void
CdbCellBuf_Iterator_Init(CdbCellBuf_Iterator *it, CdbCellBuf *cellbuf);


/*
 * CdbCellBuf_Iterator_InitToEnd
 *
 * Initializes caller's CdbCellBuf_Iterator struct, positioning the iterator
 * after the last cell.  Equivalent to:
 *
 *      CdbCellBuf_Iterator_Init(it, cellbuf);
 *      CdbCellBuf_Iterator_SetPos(it, CdbCellBuf_Length(cellbuf));
 */
static inline void
CdbCellBuf_Iterator_InitToEnd(CdbCellBuf_Iterator *it, CdbCellBuf *cellbuf)
{
    Assert(it &&
           cellbuf &&
           cellbuf->cellbytes > 0);

    it->cnext = cellbuf->cfree;
    it->cend = cellbuf->cend;
    it->cellbuf = cellbuf;
    it->cbeg = cellbuf->cbeg;
    it->begoff = cellbuf->nfull_total * cellbuf->cellbytes -
                    (cellbuf->cfree - cellbuf->cbeg);
}                               /* CdbCellBuf_Iterator_InitToEnd */


/*
 * CdbCellBuf_Iterator_NextCell
 *
 * If iterator 'it' is positioned before a cell, returns a pointer to the cell
 * and advances the iterator past that cell.  Else returns NULL and leaves the
 * iterator unchanged.
 *
 * The iterator will reach new items added by CdbCellBuf_Append() during
 * or after the traversal.  Even when the end has been reached, the caller
 * can add more items and continue calling CdbCellBuf_Iterator_NextCell() to
 * retrieve them.
 */
static inline void *
CdbCellBuf_Iterator_NextCell(CdbCellBuf_Iterator *it)
{
    char   *cell = it->cnext;

    if (cell == it->cellbuf->cfree)
        cell = NULL;
    else if (cell < it->cend)
    {
        Assert(cell >= it->cbeg);
        it->cnext += it->cellbuf->cellbytes;
    }
    else
    {
        Assert(cell == it->cend);
        cell = CdbCellBuf_Iterator_NextCellHelper(it);
    }

    return cell;
}                               /* CdbCellBuf_Iterator_NextCell */


/*
 * CdbCellBuf_Iterator_PrevCell
 *
 * If iterator 'it' is positioned after a cell, returns a pointer to the
 * cell and repositions the iterator before that cell.  Else returns NULL
 * and leaves the iterator unchanged.
 */
static inline void *
CdbCellBuf_Iterator_PrevCell(CdbCellBuf_Iterator *it)
{
    char   *cell;

    if (it->cnext > it->cbeg)
    {
        Assert(it->cnext <= it->cend);
        it->cnext -= it->cellbuf->cellbytes;
        cell = it->cnext;
    }
    else
    {
        Assert(it->cnext == it->cbeg);
        cell = CdbCellBuf_Iterator_PrevCellHelper(it);
    }

    return cell;
}                               /* CdbCellBuf_Iterator_PrevCell */


/*
 * CdbCellBuf_Iterator_CellAt
 *
 * Returns a pointer to the cell at a specified position relative to the
 * iterator's current position; or NULL if the specified position would
 * be out of bounds.  Does not affect the position or state of the iterator.
 *
 * relCellIndex == 0 returns the same value that CdbCellBuf_Iterator_NextCell
 * would return, but does not advance the iterator.
 *
 * relCellIndex == -1 returns the same value that CdbCellBuf_Iterator_PrevCell
 * would return, without repositioning the iterator.
 */
static inline void *
CdbCellBuf_Iterator_CellAt(CdbCellBuf_Iterator *it, long relCellIndex)
{
    long    relCellOff = relCellIndex * it->cellbuf->cellbytes;
    char   *cell = it->cnext + relCellOff;

    if (cell >= it->cbeg &&
        cell < it->cend)
    {
        if (relCellIndex >= 0 &&
            it->cend == it->cellbuf->cend &&
            cell >= it->cellbuf->cfree)
            cell = NULL;
    }
    else
        cell = CdbCellBuf_Iterator_CellAtHelper(it, relCellOff);

    return cell;
}                               /* CdbCellBuf_Iterator_CellAt */


/*
 * CdbCellBuf_Iterator_GetPos
 *
 * Returns the number of cells preceding the current iterator position.
 */
static inline long
CdbCellBuf_Iterator_GetPos(const CdbCellBuf_Iterator *it)
{
    CdbCellBuf         *cellbuf = it->cellbuf;
    long                pos;

    Assert(cellbuf &&
           cellbuf->cellbytes > 0 &&
           it->cnext >= it->cbeg &&
           it->cnext <= it->cend);

    pos = (long)(it->cnext - it->cbeg + it->begoff) / cellbuf->cellbytes;

    Assert(pos >= 0 &&
           pos <= cellbuf->nfull_total);

    return pos;
}                               /* CdbCellBuf_Iterator_GetPos */


/*
 * CdbCellBuf_Iterator_SetPos
 *
 * Positions the iterator before the cell whose 0-based index is
 * 'nextCellIndex'.  The first call to CdbCellBuf_Iterator_NextCell()
 * will return a pointer to the specified cell (or NULL if the starting
 * position equals the number of occupied cells.)
 *
 * If nextCellIndex == 0, positions the iterator before the first cell.
 * If nextCellIndex == CdbCellBuf_Length(), positions the iterator after
 * the last cell.
 *
 * An internal error is raised if nextCellIndex is outside the bounds
 *      0 <= nextCellIndex <= CdbCellBuf_Length(it->cellbuf)
 */
static inline void
CdbCellBuf_Iterator_SetPos(CdbCellBuf_Iterator *it, long nextCellIndex)
{
    long    nextCellOff;

    Insist(nextCellIndex <= it->cellbuf->nfull_total);

    nextCellOff = nextCellIndex * it->cellbuf->cellbytes;

    /* Reposition within current block? */
    if (nextCellOff >= it->begoff &&
        nextCellOff <= (long)(it->cend - it->cbeg) + it->begoff)
        it->cnext = nextCellOff - it->begoff + it->cbeg;

    else
        CdbCellBuf_Iterator_SetPosHelper(it, nextCellOff);
}                               /* CdbCellBuf_Iterator_SetPos */


/*
 * CdbCellBuf_Iterator_AtBegin
 *
 * Returns 'true' if iterator is positioned before the first cell or if
 * the cellbuf is empty.  Returns 'false' if there is a cell preceding
 * the iterator position.
 */
static inline bool
CdbCellBuf_Iterator_AtBegin(const CdbCellBuf_Iterator *it)
{
    return (it->cbeg == it->cnext &&
            it->begoff == 0);
}                               /* CdbCellBuf_Iterator_AtBegin */


/*
 * CdbCellBuf_Iterator_AtEnd
 *
 * Returns 'true' if iterator is positioned after the last cell or if
 * the cellbuf is empty, i.e., if CdbCellBuf_Iterator_NextCell() would
 * return NULL.  Returns 'false' if iterator is positioned before a cell.
 */
static inline bool
CdbCellBuf_Iterator_AtEnd(const CdbCellBuf_Iterator *it)
{
    CdbCellBuf *cellbuf = it->cellbuf;
    bool        atend;

    if (it->cnext == cellbuf->cfree)
        atend = true;

    /* Maybe tail bunch is empty and iterator is at end of previous bunch */
    else if (it->cnext == it->cend &&
             it->cnext - it->cbeg + it->begoff == cellbuf->nfull_total * cellbuf->cellbytes)
        atend = true;

    else
        atend = false;

    return atend;
}                               /* CdbCellBuf_Iterator_AtEnd */


/*
 * CdbCellBuf_Iterator_Length
 *
 * Returns the number of cells in the associated cellbuf.
 *
 * Equivalent to
 *      CdbCellBuf_Length(it->cellbuf)
 */
static inline long
CdbCellBuf_Iterator_Length(const CdbCellBuf_Iterator *it)
{
    return it->cellbuf->nfull_total;
}                               /* CdbCellBuf_Iterator_Length */


#endif   /* CDBCELLBUF_H */
