예제 #1
0
  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;
  }
예제 #2
0
  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;
    }
  }