public int deleteRecord(String tableName, List<Condition> conditions) throws TableNotFoundException, Exception { Table table = cm.getTable(tableName); if (table == null) throw new TableNotFoundException(tableName); int count = 0; for (int blockOffset = 0; blockOffset < table.blockNum; blockOffset++) { BufferNode bn = bm.getBufferNode(table.name + ".table", blockOffset); byte[] block = bn.data; int recordNum = getRecordNum(block); int recordIndex = 0; int accessedRecordNum = 0; int nextDeleted = getInsertIndex(block); int prevDeleted = -1; ArrayList<Index> allTableIndices = cm.getAllIndicesOfTable(tableName); while (accessedRecordNum < recordNum) { int pos = getPositionFromIndex(table, recordIndex); if (block[pos] == EMPTY) { // record is empty, skip recordIndex++; continue; } byte[] recordBytes = bn.getBytes(pos + 1, table.totalLength); if (matchAllCond(table, recordBytes, conditions)) { block[pos] = EMPTY; if (recordIndex < nextDeleted) { setNextInsertIndex(block, table, prevDeleted, recordIndex); setNextInsertIndex(block, table, recordIndex, nextDeleted); prevDeleted = recordIndex; } else { int nextOfNext = getNextInsertIndex(block, table, nextDeleted); setNextInsertIndex(block, table, nextDeleted, recordIndex); setNextInsertIndex(block, table, recordIndex, nextOfNext); nextDeleted = nextOfNext; prevDeleted = recordIndex; } decRecordNum(block); // there remains some space for insertion if (table.nextInsertBlock > blockOffset) table.nextInsertBlock = blockOffset; // Delete in index for (Index idx : allTableIndices) { byte[] key = Arrays.copyOfRange(recordBytes, idx.pos, idx.pos + idx.columnLength); im.deleteKey(idx, key); } bn.isWritten = true; count++; } recordIndex++; accessedRecordNum++; } } return count; }
public void insertRecord(String tableName, List<String> row) throws TableNotFoundException, UniqueKeyException, Exception { Table table = cm.getTable(tableName); if (table == null) throw new TableNotFoundException(tableName); byte[] bytesToInsert = getInsertBytes(table, row); // check uniqueness ArrayList<Index> allTableIndices = cm.getAllIndicesOfTable(tableName); for (Index idx : allTableIndices) { byte[] key = Arrays.copyOfRange(bytesToInsert, idx.pos, idx.pos + idx.columnLength); if (im.searchEqual(idx, key) != null) throw new UniqueKeyException(idx.indexName); } // Use free list for insertion and deletion int recordSize = table.totalLength + POINTER_SIZE; while (true) { // BufferNode bn = bm.getIfIsInBuffer(table.name + ".table", table.nextInsertBlock); BufferNode bn = bm.getBufferNode(table.name + ".table", table.nextInsertBlock); byte[] block = bn.data; int insertIndex = getInsertIndex(block); int pos = getPositionFromIndex(table, insertIndex); // No free space, get a new block if (pos + recordSize > BufferManager.BLOCK_SIZE) { table.nextInsertBlock++; if (table.nextInsertBlock >= table.blockNum) bm.addBlockInFile(table); continue; } // Write to buffer block[pos] = NOT_EMPTY; System.arraycopy(bytesToInsert, 0, block, pos + 1, table.totalLength); // Modify available insert index value and increase record number int nextIndex = getNextInsertIndex(block, table, insertIndex); setInsertIndex(block, nextIndex); incRecordNum(block); // Update index for (Attribute attr : table.attributes) { if (!attr.index.equals("")) { // has index Index idx = cm.getIndex(attr.index); byte[] key = Arrays.copyOfRange(bytesToInsert, idx.pos, idx.pos + idx.columnLength); im.insertKey(idx, key, table.nextInsertBlock, pos); } } bn.isWritten = true; return; } }