/** * Create an index file for the specified column. * * @param colname the column's name * @return the time it took to run this method. * @throws Exception */ public long createIndexFile() throws Exception { long s = System.currentTimeMillis(); // fill idx file with hashsize empty records/lines (empty means filled with spaces) int pkindex = def.getColPosition(def.getPK()); if (pkindex == -1) { throw new Exception("Primary key does not exist"); } Integer[] size = def.getSizes(); int recordSize = idxFixedRecordLength() + size[pkindex]; StringBuffer temp = new StringBuffer(); for (int i = 0; i < recordSize - 2; i++) { temp.append(" "); } indexFile.seek(0); for (int i = 0; i < this.hashsize; i++) { indexFile.writeBytes(temp + "\r\n"); } int table_pos = 0; // create an index entry for each row present in the tbl-file (for column=colname) String line = null; tableFile.seek(0); while ((line = tableFile.readLine()) != null) { // get column value (don't strip the spaces) String pkvalue = line.split("#")[pkindex]; addIndexEntry(table_pos, pkvalue); table_pos++; } long e = System.currentTimeMillis(); return e - s; }
/** * Create an index entry in the idx file of the specified column. * * @param tablePosition position or line nr in table *.tbl * @param pkValue the value of the primary key to create an index entry for * @throws Exception */ protected void addIndexEntry(int tablePosition, String pkValue) throws Exception { if (!indexExists(def.getPK())) { throw new Exception("No index created"); } int pkindex = def.getColPosition(def.getPK()); if (pkindex == -1) { throw new Exception("Primary key does not exist"); } Integer[] size = def.getSizes(); if (pkValue.length() > TableDefinition.INTEGER_SIZE) { throw new Exception("Supplied pkValue too large"); } else { // make sure key value has appropriate length StringBuffer temp = new StringBuffer(); temp.append(pkValue); for (int i = 0; i < TableDefinition.INTEGER_SIZE - pkValue.length(); i++) { temp.append(' '); } pkValue = temp.toString(); } // calculate index = hash value String s_value = pkValue.trim(); int indexPosition = hash(s_value); int recordSize = idxFixedRecordLength() + size[pkindex]; indexFile.seek(indexPosition * recordSize); String line = indexFile.readLine(); if (line.substring(0, 1).equals(" ")) { // empty record, reset file pointer and fill record indexFile.seek(indexPosition * recordSize); String indexPositionFormatted = String.format("%-5s", Integer.toString(indexPosition)); String tablePositionFormatted = String.format("%-5s", Integer.toString(tablePosition)); String indexRecord = indexPositionFormatted + "# #" + pkValue + "#" + tablePositionFormatted + "#" + "null " + "\r\n"; indexFile.writeBytes(indexRecord); } else { String[] parts = line.split("#"); if (parts[1].equals("D")) { // Deleted record, reset file pointer, fill record but keep previous link ! indexFile.seek(indexPosition * recordSize); String indexPositionFormatted = String.format("%-5s", Integer.toString(indexPosition)); String tablePositionFormatted = String.format("%-5s", Integer.toString(tablePosition)); String indexRecord = indexPositionFormatted + "# #" + pkValue + "#" + tablePositionFormatted; indexFile.writeBytes(indexRecord); } else { // Collision found ! a valid record is found, so add new record at EOF // Calculate new record number int newIndexPosition = (int) (indexFile.length() / recordSize); String newIndexPositionFormatted = String.format("%-5s", Integer.toString(newIndexPosition)); String tablePositionFormatted = String.format("%-5s", Integer.toString(tablePosition)); // reset file pointer and update the current record indexFile.seek((indexPosition * recordSize) + (recordSize - 2 - 5)); indexFile.write(newIndexPositionFormatted.toString().getBytes()); // move file pointer to EOF and append new record indexFile.seek(indexFile.length()); String indexRecord = newIndexPositionFormatted + "# #" + pkValue + "#" + tablePositionFormatted + "#" + "null " + "\r\n"; indexFile.writeBytes(indexRecord); } } }