package com.googlecode.prolog_cafe.lang;
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 {
    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]);
	}
    }
}
