private void restoreClusterFromWAL() throws IOException {
    ODiskWriteAheadLog log =
        new ODiskWriteAheadLog(4, -1, 10 * 1024L * OWALPage.PAGE_SIZE, storage);
    OLogSequenceNumber lsn = log.begin();

    List<OWALRecord> atomicUnit = new ArrayList<OWALRecord>();

    boolean atomicChangeIsProcessed = false;
    while (lsn != null) {
      OWALRecord walRecord = log.read(lsn);
      atomicUnit.add(walRecord);

      if (!atomicChangeIsProcessed) {
        Assert.assertTrue(walRecord instanceof OAtomicUnitStartRecord);
        atomicChangeIsProcessed = true;
      } else if (walRecord instanceof OAtomicUnitEndRecord) {
        atomicChangeIsProcessed = false;

        for (OWALRecord restoreRecord : atomicUnit) {
          if (restoreRecord instanceof OAtomicUnitStartRecord
              || restoreRecord instanceof OAtomicUnitEndRecord
              || restoreRecord instanceof OFileCreatedWALRecord
              || restoreRecord instanceof ONonTxOperationPerformedWALRecord) continue;

          final OUpdatePageRecord updatePageRecord = (OUpdatePageRecord) restoreRecord;

          final long fileId = updatePageRecord.getFileId();
          final long pageIndex = updatePageRecord.getPageIndex();

          if (!testWriteCache.isOpen(fileId)) testReadCache.openFile(fileId, testWriteCache);

          OCacheEntry cacheEntry = testReadCache.load(fileId, pageIndex, true, testWriteCache);
          if (cacheEntry == null) {
            do {
              if (cacheEntry != null) readCache.release(cacheEntry, testWriteCache);

              cacheEntry = testReadCache.allocateNewPage(fileId, testWriteCache);
            } while (cacheEntry.getPageIndex() != pageIndex);
          }
          cacheEntry.acquireExclusiveLock();
          try {
            ODurablePage durablePage = new ODurablePage(cacheEntry, null);
            durablePage.restoreChanges(updatePageRecord.getChanges());
            durablePage.setLsn(updatePageRecord.getLsn());

            cacheEntry.markDirty();
          } finally {
            cacheEntry.releaseExclusiveLock();
            testReadCache.release(cacheEntry, testWriteCache);
          }
        }
        atomicUnit.clear();
      } else {
        Assert.assertTrue(
            walRecord instanceof OUpdatePageRecord
                || walRecord instanceof OFileCreatedWALRecord
                || walRecord instanceof ONonTxOperationPerformedWALRecord);
      }

      lsn = log.next(lsn);
    }

    Assert.assertTrue(atomicUnit.isEmpty());
    log.close();
  }
 @Override
 public OCacheEntry loadPage(
     long fileId, long pageIndex, boolean checkPinnedPages, OWriteCache writeCache, int pageCount)
     throws IOException {
   return readCache.load(fileId, pageIndex, checkPinnedPages, writeCache, pageCount);
 }