Пример #1
0
  /**
   * Lock the blocks. The blocks are locked in ascending block id order to avoid deadlocks.
   *
   * @param isWrite if true, the block should be locked for writing
   */
  public void lock() throws SQLException {
    if (_isNonLocking) return;

    if (_isLocked) {
      throw new IllegalStateException(L.l("blocks are already locked"));
    }
    _isLocked = true;

    if (_thread != Thread.currentThread()) throw new IllegalStateException();

    int len = _tableIterators.length;

    for (int i = 0; i < len; i++) {
      Block bestBlock = null;
      long bestId = Long.MAX_VALUE;

      loop:
      for (int j = 0; j < len; j++) {
        TableIterator iter = _tableIterators[j];

        if (iter == null) continue;

        Block block = iter.getBlock();

        if (block == null) continue;

        long id = block.getBlockId();
        if (bestId <= id) continue;

        for (int k = 0; k < i; k++) {
          if (_blockLocks[k] == block) continue loop;
        }

        bestId = id;
        bestBlock = block;
      }

      try {
        if (bestBlock == null) {
        } else if (_isWrite) {
          bestBlock.getWriteLock().tryLock(_xa.getTimeout(), TimeUnit.MILLISECONDS);
        } else {
          bestBlock.getReadLock().tryLock(_xa.getTimeout(), TimeUnit.MILLISECONDS);
        }
      } catch (Exception e) {
        throw new IllegalStateException(e);
      }

      // assignment must be after obtaining lock because the unlock
      // requires a lock
      _blockLocks[i] = bestBlock;
    }
  }
Пример #2
0
  /** Returns the following block. */
  public boolean nextBlock() throws IOException {
    byte[] buffer = _buffer;

    Block block = _block;
    _block = null;
    _buffer = null;

    if (block != null) {
      block.free();
    }

    _blockId = _table.firstRowBlock(_blockId + Table.BLOCK_SIZE);

    if (_blockId < 0) {
      return false;
    }

    block = _xa.readBlock(_table, _blockId);

    buffer = block.getBuffer();
    _block = block;
    _buffer = buffer;
    _rowOffset = 0;

    return true;
  }
Пример #3
0
  public void close() throws SQLException {
    Thread thread = _thread;
    _thread = null;

    unlock();

    if (thread != null && thread != Thread.currentThread()) {
      throw new IllegalStateException();
    }

    DbTransaction xa = _xa;
    _xa = null;

    // db/0a10
    if (xa != null && xa.isAutoCommit()) xa.commit();
  }
Пример #4
0
  /**
   * Unlock the blocks. The blocks are unlocked in descending order.
   *
   * @param isWrite if true, the block should be unlocked for writing
   */
  public void unlock() throws SQLException {
    if (_isNonLocking) return;

    if (!_isLocked) {
      return;
    }

    _isLocked = false;

    if (_thread != null && _thread != Thread.currentThread())
      throw new IllegalStateException(
          String.valueOf(_thread) + " current " + Thread.currentThread());

    int len = _blockLocks.length;

    // need to unlock first since the writeData/commit will wait for
    // write locks to clear before committing
    for (int i = len - 1; i >= 0; i--) {
      Block block = _blockLocks[i];

      if (block == null) {
      } else if (_isWrite) {
        block.getWriteLock().unlock();
      } else {
        block.getReadLock().unlock();
      }
    }

    try {
      _xa.writeData();
    } finally {
      for (int i = len - 1; i >= 0; i--) {
        Block block = _blockLocks[i];
        _blockLocks[i] = null;

        if (block == null) {
        } else if (_isWrite) {
          try {
            block.commit();
          } catch (Exception e) {
            log.log(Level.FINE, e.toString(), e);
          }
        }
      }
    }
  }
Пример #5
0
  /** Sets the next row. */
  public void setRow(long rowAddr) throws IOException {
    long blockId = _table.addressToBlockId(rowAddr);

    if (blockId != _blockId) {
      _blockId = blockId;

      Block block = _block;
      _block = null;
      _buffer = null;

      if (block != null) {
        block.free();
      }

      _block = _xa.readBlock(_table, _blockId);
      _buffer = _block.getBuffer();
    }

    _rowOffset = (int) (rowAddr & BlockStore.BLOCK_OFFSET_MASK);
  }
Пример #6
0
  public void setDirty() throws SQLException {
    _xa.addUpdateBlock(_block);

    _block.setDirty(_rowOffset, _rowOffset + _rowLength);
  }