/*
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection;

import java.util.Collection;

/**
 * Collections implementing this interface stores data inside one memory block.
 * Altough it isn't so relevant from memory locality perspective (because JVM uses managed heap),
 * it is if we want make assumptions about potential reallocations inside collections.
 *
 * Offers few methods for space management: we can check allocated capacity, reserve memory or free unused.
 *
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 * @param <T> T
 */
public interface BlockCollection<T> extends Collection<T> {
    
    /**
     * Ensures that this collection can contain the given number of entries
     * without resizing.
     * @param capacity the new minimum capacity for this array list.
     * @return true if there was enough memory to reallocate the collection.
     */
    boolean reserve(int capacity);

    /**
     * Returns size of block allocated by collection.
     * Collection shouldn't reallocate on next insertions as long as "size" is lower than "capacity"
     *
     * @return int
     */
    int capacity();

    /**
     * Reallocates this collection, making the capacity as small as possible.
     *
     * <P>This method reallocates the internal table to the smallest possible size. 
     * It can be used when the collection will not be changed anymore, so
     * to optimize access speed and size.
     *
     * <P>If the table size is already the minimum possible, this method does nothing.
     *
     * @return true if there was enough memory to trim the collection.
     * @see #trim(int)
     */
    boolean trim();

    /**
     * Reallocates this collection if the table is too large.
     *
     * <P>Let <var>N</var> be the smallest capacity that can hold
     * <code>max(n,{@link #size()})</code> entries, still satisfying internal constraints. 
     * If the current table size is smaller than or equal to
     * <var>N</var>, this method does nothing. Otherwise, it resizes this set
     * in a table of size <var>N</var>.
     *
     * <P>This method is useful when reusing collections. {@linkplain #clear() Clearing a
     * set} leaves in most situations the collection capacity untouched. If you are reusing a collection many
     * times, you can call this method with a typical size to avoid keeping
     * around a very large memory usage just because of a few large transient sets.
     *
     * @param n the threshold for the trimming.
     * @return true if there was enough memory to trim the set.
     * @see #trim()
     */
    boolean trim(int n);
    
}
