package jp.ac.kobe_u.cs.prolog.lang;
import java.io.Serializable;
import java.util.LinkedList;
/**
 * Internal database for dynamic predicates.<br>
 *
 * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
 * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
 * @version 1.1
 */
public class InternalDatabase implements Serializable {
    protected static final int DEFAULT_SIZE = 100000;

    /** Maximum size of enties. Initial size is <code>100000</code>. */
    protected int maxContents;

    /** An array of <code>Term</code> entries. */
    protected Term[] buffer;

    /* For GC */
    /** A list of reusable entry indices. */
    protected LinkedList<Integer> reusableIndices = new LinkedList<Integer>();

    /** the top index of this <code>InternalDatabase</code>. */
    protected int top;

    /** Constructs a new internal dababase. */
    public InternalDatabase() {
	this(DEFAULT_SIZE);
    }

    /** Constructs a new internal dababase with the given size. */
    public InternalDatabase(int n) {
	maxContents = n;
	buffer = new Term[Math.min(maxContents, DEFAULT_SIZE)];
	top = -1;
    }

    /** Discards all entries. */
    public void init() { eraseAll(); }

    /** Inserts an entry to this <code>InternalDatabase</code>. */
    public int insert(Term t) {
	try {
	    if (reusableIndices.isEmpty()) {
		buffer[++top] = t;
		return top;
	    } else {
		int i = reusableIndices.remove();
		//		System.out.println("Reuse " + i);
		buffer[i] = t;
		return i;
	    }
	} catch (ArrayIndexOutOfBoundsException e) {
	    if (maxContents == buffer.length)
	      throw new SystemException("internal database capacity reached");
	    int len = buffer.length;
	    Term[] new_buffer = new Term[Math.min(len+10000, maxContents)];
	    for(int i=0; i<len; i++){
		new_buffer[i] = buffer[i];
	    }
	    buffer = new_buffer;
	    buffer[top] = t;
	    return top;
	}
    }

    /** Returns an entry with the given index from this <code>InternalDatabase</code>. */
    public Term get(int i) {
	return buffer[i];
    }

    /** Erases an entry with the given index from this <code>InternalDatabase</code>. */
    public Term erase(int i) {
	Term t = buffer[i];
	buffer[i] = null;
	//	System.out.println("add Reuse index" + i);
	reusableIndices.add(i);
	return t;
    }

    /** Discards all entries. */
    protected void eraseAll() {
	while (! empty()) {
	    buffer[top--] = null;
	}	
    }

    /** Tests if this has no entry. */
    public boolean empty() {
	return top == -1;
    }

    /** Returns the value of <code>top</code>. 
     * @see #top
     */
    public int top() { return top; }

    /** Shows the contents of this <code>InternalDatabase</code>. */
    public void show() {
	if (empty())
	    System.out.println("{internal database is empty!}");
	System.out.println("{reusable indices: " + reusableIndices.toString() + "}");
	for (int i=0; i<=top; i++) {
	    System.out.print("internal database[" + i + "]: ");
	    System.out.println(buffer[i]);
	}
    }
}
