public void rollbackRow(Session session, Row row, int changeAction, int txModel) {

    switch (changeAction) {
      case RowAction.ACTION_DELETE:
        if (txModel == TransactionManager.LOCKS) {
          ((RowAVL) row).setNewNodes(this);
          indexRow(session, row);
        }
        break;

      case RowAction.ACTION_INSERT:
        if (txModel == TransactionManager.LOCKS) {
          delete(session, row);
          remove(row.getPos());
        }
        break;

      case RowAction.ACTION_INSERT_DELETE:

        // INSERT + DELETE
        if (txModel == TransactionManager.LOCKS) {
          remove(row.getPos());
        }
        break;
    }
  }
  public CachedObject getAccessor(Index key) {

    NodeAVL node = (NodeAVL) accessorList[key.getPosition()];

    if (node == null) {
      return null;
    }

    if (!node.isInMemory()) {
      RowAVL row = (RowAVL) get(node.getPos(), false);

      node = row.getNode(key.getPosition());
      accessorList[key.getPosition()] = node;
    }

    return node;
  }
  /** Only unlinks nodes. Is not a destroy() method */
  public void delete(PersistentStore store) {

    RowAVLDisk row = this;

    if (!row.keepInMemory(true)) {
      row = (RowAVLDisk) store.get(row, true);
    }

    super.delete(store);
    row.keepInMemory(false);
  }
  public final void indexRows() {

    RowIterator it = rowIterator();

    for (int i = 1; i < indexList.length; i++) {
      setAccessor(indexList[i], null);
    }

    while (it.hasNext()) {
      Row row = it.getNextRow();

      ((RowAVL) row).clearNonPrimaryNodes();

      for (int i = 1; i < indexList.length; i++) {
        indexList[i].insert(null, this, row);
      }
    }
  }
  boolean insertIndexNodes(Index primaryIndex, Index newIndex) {

    int position = newIndex.getPosition();
    RowIterator it = primaryIndex.firstRow(this, false);
    int rowCount = 0;
    HsqlException error = null;

    try {
      while (it.hasNext()) {
        Row row = it.getNextRow();

        ((RowAVL) row).insertNode(position);

        // count before inserting
        rowCount++;

        newIndex.insert(null, this, row);
      }

      return true;
    } catch (java.lang.OutOfMemoryError e) {
      error = Error.error(ErrorCode.OUT_OF_MEMORY);
    } catch (HsqlException e) {
      error = e;
    }

    // backtrack on error
    // rowCount rows have been modified
    it = primaryIndex.firstRow(this, false);

    for (int i = 0; i < rowCount; i++) {
      Row row = it.getNextRow();
      NodeAVL backnode = ((RowAVL) row).getNode(0);
      int j = position;

      while (--j > 0) {
        backnode = backnode.nNext;
      }

      backnode.nNext = backnode.nNext.nNext;
    }

    throw error;
  }