/* @(#) DBSession.java 1.3, 98/09
 * Copyright (c) 1997, 1998 Sav. All Rights Reserved.
 */
import Sav.*;
import java.io.*;
import java.util.*;
/** Table indexing, selecting indexes (namely row numbers). 
 *  The table rows are kept in outer file. 
 */
class TableIndex {
String DBName;
String tableName;
int rowMax = 1000;
int columnMax;
String bufTable[][] = new String[rowMax + 1][];
int rowNumber = 0;
int rowIndex = 0;

Association aRTable;
Association aIField[];

TableIndex(String DBName, String tableName, int columnMax) throws Exception {
	this.DBName = DBName;
	this.tableName = tableName;
	this.columnMax = columnMax;
	aRTable = new Association(DBName);
	aRTable.con(tableName).con(PN.RELATION).fix();
	aIField = new Association[columnMax + 1];
	for (int j = 1; j <= columnMax; ++j) {
		aIField[j] = (Association) aRTable.clone();
		aIField[j].con("#" + j).con(PN.IDENTITY).fix();
	}
}//TableIndex()

void createIndex(DataInputStream fTable) throws Exception {
	long memorySize;
	Runtime runTime = Runtime.getRuntime();

	System.out.println("READING " + " ...");
	String line = fTable.readLine();
	line = fTable.readLine();
	while (true) {
		if (++rowIndex > PN.MAX_NUMERIC)
			new IndexOutOfBoundsException("rowIndex > " + PN.MAX_NUMERIC);
		bufTable[++rowNumber] = new String[columnMax + 1];
		bufTable[rowNumber][0] = "#" + rowIndex;
		StringTokenizer tokens = new StringTokenizer(line, "\t\n\r");
		for (int j = 1; j <= columnMax; ++j) {
			if (tokens.hasMoreTokens()) {
				bufTable[rowNumber][j] = tokens.nextToken();
			}
		}
		try {
			line = fTable.readLine();
		} catch (EOFException e) {
			line = null;
		}

		if (rowNumber == rowMax || line == null) {
			System.out.println(rowIndex);
    		System.out.println("INDEXING " + " ...");
			for (int j = 1; j <= columnMax; ++j) {
				for (int i = 1; i <= rowNumber; ++i) {
					if (bufTable[i][j] == null) continue;

					aIField[j].con(bufTable[i][j]).con(PN.RELATION_DEF);
					aIField[j].set(bufTable[i][0]);
					aIField[j].regain();
				}
			}

			memorySize = runTime.totalMemory();
			System.out.println("memorySize = " + memorySize);
			System.out.println("STORING ...");
			rowNumber = 0;
			aRTable.store();
			if (line == null) return;
			runTime.gc();
       		System.out.println("READING " + " ...");
		}
	}
}//createIndex()

void select(String queryRow[]) throws Exception {
	Association aResultSet = null;
	Concept cRowIndex = null;
	int columnBegin = 0;
	System.out.println("QUERY1 for " + DBName + '.' + tableName);
	while (++columnBegin <= columnMax) {
		if (queryRow[columnBegin] == null) continue;
		aIField[columnBegin].con(queryRow[columnBegin]).con(PN.RELATION_DEF);
		aResultSet = aIField[columnBegin];
		break;
	}

	for (int j = columnBegin + 1; j <= columnMax; ++j) {
		if (queryRow[j] != null) {
			aIField[j].con(queryRow[j]).con(PN.RELATION_DEF);
			aResultSet = aIField[j].get(aResultSet);

//			Runtime runTime = Runtime.getRuntime();
//			long memorySize = runTime.totalMemory();
//			if (memorySize > 5000000) {
//				System.out.println(memorySize + " Store ...");
//				aRTable.store();
//				runTime.gc();
//			}

		}
	}
//	System.out.println("\nPress ENTER to output.");
//	System.in.read();

	int power = 0;
	cRowIndex = aResultSet.getFirst();
	while (cRowIndex != null) {
		++power;
		System.out.println(cRowIndex.getName());
		cRowIndex = aResultSet.getNext();
	}
	System.out.println("power = " + power);
}//select()
}//TableIndex class

class DBSession {
public static void main(String args[]) throws Exception {
	String DBName = "Soft";
	String tableName = "Reference";
	int columnMax = 10;
	TableIndex tableIndex = new TableIndex(DBName, tableName, columnMax);

	InputStream fileInput = new FileInputStream(tableName + ".txt");
	InputStream bufferInput = new BufferedInputStream(fileInput, 81920);
	DataInputStream fTable = new DataInputStream(bufferInput);
	tableIndex.createIndex(fTable);
/*Control query*/
	String queryRow[] = tableIndex.bufTable[4];
	queryRow[2] = null;
	queryRow[5] = null;
	tableIndex.select(queryRow);
//	System.out.println("\nPress ENTER to finish.");
//	System.in.read();
//	System.in.read();
}//main()
}//DBSession