package s3.services.memory.mostlyCopying;

/**
 * BlockData maintains the overall structure of the heap.  It is
 * used to allocate blocks of memory, and to track whether a block of
 * memory is free, in from-space, grey, or black.<p>
 * 
 * I can think of three ways to represent metadata in a mostly-copying
 * collector
 * <ul>
 * <li> Barlett's scheme with generation numbers
 * <li> The doubly linked freelist in {@link BlockList}.
 * <li> The bit-vectors in {@link VecList}.
 * </ul>
 *
 * I think the bit-vector approach has the best performance, and am
 * firmly convinced that the doubly linked approach has the worst.
 * The doubly-linked list code is riddled with useful assertions, and
 * a head to head comparison of all three may be interesting.  Hence,
 * an interface is needed.
 * 
 * @author <a href=mailto://baker29@cs.purdue.edu> Jason Baker </a>
 **/
public interface BlockData {
    /**
     * Allocate a contiguous group of nBlocks-many blocks.  If a GC is
     * in progress, these blocks are to be considered grey.
     **/
    int alloc(int nblocks);

    /**
     * Called when GC is initiated.
     **/
    void startGC(boolean isFull);

    /**
     * Return false if this block is free, or was returned by alloc.
     * Return true if this is the nth block, where n > 1, in a
     * multi-block allocation
     */
    boolean isContinued(int block);

    /**
     * return the base block index for a block for which isContinued
     * is true.
     **/
    int getBase(int block);

    /**
     * return the size of an allocated block (not a continued block)
     **/
    int getSize(int block);

    /**
     * Return true if this block is eligible to be reclaimed.  Return
     * false if the block is free, grey, black, or continued
     **/
    boolean inFromSpace(int block);

    /**
     * Mark a block as pinned for this collection cycle.  This method
     * should be called after startGC, but before endGC.  Pin should
     * be called on a block in the from space, and has the effect of
     * removing it from the from space.
     **/
    void pin(int block);

    /**
     * Iterate over all blocks allocated since startGC was called.
     * Pinned blocks may be walked here, or may be walked together
     * with generational roots.  (We may want to walk only parts of
     * large arrays that act as generational roots, but the interface
     * isn't here yet.)
     **/
    void walkGrey(Manager.BlockWalker w);

    /**
     * This method must be called after the garbage collection is
     * finished. 
     **/
    void endGC();

    /**
     * Iterate over all ranges of free blocks
     **/
    void walkFree(Manager.BlockWalker w);

    /**
     * Iterate over all freshly allocated blocks
     **/
    void walkWhite(Manager.BlockWalker w);
}
