/**
   * Writes out the specified Row. Will write only the Nodes or both Nodes and table row data
   * depending on what is not already persisted to disk.
   */
  private void saveRow(CachedObject row) throws IOException {

    setFileModified();
    rowOut.reset();
    row.write(rowOut);
    dataFile.seek((long) row.getPos() * cacheFileScale);
    dataFile.write(rowOut.getOutputStream().getBuffer(), 0, rowOut.getOutputStream().size());
  }
  /**
   * For a CacheObject that had been previously released from the cache. A new version is
   * introduced, using the preallocated space for the object.
   */
  public void restore(CachedObject object) throws IOException {

    int i = object.getPos();

    cache.put(i, object);

    // for text tables
    if (storeOnInsert) {
      saveRow(object);
    }
  }
  /**
   * For a CacheObject that had been previously released from the cache. A new version is
   * introduced, using the preallocated space for the object.
   */
  public synchronized void restore(CachedObject object) throws IOException {

    int i = object.getPos();

    cache.put(i, object);

    // was previously used for text tables
    if (storeOnInsert) {
      saveRow(object);
    }
  }
  public synchronized CachedObject get(int i, PersistentStore store, boolean keep)
      throws HsqlException {

    if (i < 0) {
      return null;
    }

    try {
      CachedObject object = cache.get(i);

      if (object == null) {
        RowInputInterface rowInput = readObject(i);

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

        object = store.get(rowInput);

        // for text tables with empty rows at the beginning,
        // pos may move forward in readObject
        i = object.getPos();

        cache.put(i, object);
      }

      if (keep) {
        object.keepInMemory(true);
      }

      return object;
    } catch (IOException e) {
      database.logger.appLog.logContext(SimpleLog.LOG_ERROR, fileName + " get pos: " + i);
      database.logger.appLog.logContext(e);

      throw Trace.error(
          Trace.DATA_FILE_ERROR, Trace.DataFileCache_makeRow, new Object[] {e, fileName});
    }
  }
 public CachedObject get(CachedObject object, boolean keep) {
   return (CachedObject) rowIdMap.get(object.getPos());
 }
  int[] writeTableToDataFile(Table table) throws IOException {

    Session session = database.getSessionManager().getSysSession();
    PersistentStore store = session.sessionData.getRowStore(table);
    RowOutputInterface rowOut = new RowOutputBinary(1024, scale);
    DoubleIntIndex pointerLookup =
        new DoubleIntIndex(table.getPrimaryIndex().sizeEstimate(store), false);
    int[] rootsArray = table.getIndexRootsArray();
    long pos = fileOffset;
    int count = 0;

    pointerLookup.setKeysSearchTarget();
    Error.printSystemOut("lookup begins: " + stopw.elapsedTime());

    RowIterator it = table.rowIterator(session);

    for (; it.hasNext(); count++) {
      CachedObject row = it.getNextRow();

      pointerLookup.addUnsorted(row.getPos(), (int) (pos / scale));

      if (count % 50000 == 0) {
        Error.printSystemOut("pointer pair for row " + count + " " + row.getPos() + " " + pos);
      }

      pos += row.getStorageSize();
    }

    Error.printSystemOut(table.getName().name + " list done: " + stopw.elapsedTime());

    count = 0;
    it = table.rowIterator(session);

    for (; it.hasNext(); count++) {
      CachedObject row = it.getNextRow();

      rowOut.reset();
      row.write(rowOut, pointerLookup);
      fileStreamOut.write(rowOut.getOutputStream().getBuffer(), 0, rowOut.size());

      fileOffset += row.getStorageSize();

      if ((count) % 50000 == 0) {
        Error.printSystemOut(count + " rows " + stopw.elapsedTime());
      }
    }

    for (int i = 0; i < rootsArray.length; i++) {
      if (rootsArray[i] == -1) {
        continue;
      }

      int lookupIndex = pointerLookup.findFirstEqualKeyIndex(rootsArray[i]);

      if (lookupIndex == -1) {
        throw Error.error(ErrorCode.DATA_FILE_ERROR);
      }

      rootsArray[i] = pointerLookup.getValue(lookupIndex);
    }

    setTransactionRowLookups(pointerLookup);
    Error.printSystemOut(table.getName().name + " : table converted");

    return rootsArray;
  }