예제 #1
0
  public void renameFile(long fileId, String oldFileName, String newFileName) throws IOException {
    synchronized (syncObject) {
      if (!files.containsKey(fileId)) return;

      final OFileClassic file = files.get(fileId);
      final String osFileName = file.getName();
      if (osFileName.startsWith(oldFileName)) {
        final File newFile =
            new File(
                storageLocal.getStoragePath()
                    + File.separator
                    + newFileName
                    + osFileName.substring(
                        osFileName.lastIndexOf(oldFileName) + oldFileName.length()));
        boolean renamed = file.renameTo(newFile);
        while (!renamed) {
          OMemoryWatchDog.freeMemoryForResourceCleanup(100);
          renamed = file.renameTo(newFile);
        }
      }

      writeNameIdEntry(new NameFileIdEntry(oldFileName, -1), false);
      writeNameIdEntry(new NameFileIdEntry(newFileName, fileId), true);

      nameIdMap.remove(oldFileName);
      nameIdMap.put(newFileName, fileId);
    }
  }
예제 #2
0
  public void close() throws IOException {
    flush();

    if (!commitExecutor.isShutdown()) {
      commitExecutor.shutdown();
      try {
        if (!commitExecutor.awaitTermination(5, TimeUnit.MINUTES))
          throw new OException("Background data flush task can not be stopped.");
      } catch (InterruptedException e) {
        OLogManager.instance().error(this, "Data flush thread was interrupted");

        Thread.interrupted();
        throw new OException("Data flush thread was interrupted", e);
      }
    }

    synchronized (syncObject) {
      for (OFileClassic fileClassic : files.values()) {
        if (fileClassic.isOpen()) fileClassic.close();
      }

      if (nameIdMapHolder != null) {
        nameIdMapHolder.setLength(0);
        for (Map.Entry<String, Long> entry : nameIdMap.entrySet()) {
          writeNameIdEntry(new NameFileIdEntry(entry.getKey(), entry.getValue()), false);
        }
        nameIdMapHolder.getFD().sync();
        nameIdMapHolder.close();
      }
    }
  }
예제 #3
0
  public boolean wasSoftlyClosed(long fileId) throws IOException {
    synchronized (syncObject) {
      OFileClassic fileClassic = files.get(fileId);
      if (fileClassic == null) return false;

      return fileClassic.wasSoftlyClosed();
    }
  }
예제 #4
0
  public boolean isOpen(long fileId) {
    synchronized (syncObject) {
      OFileClassic fileClassic = files.get(fileId);
      if (fileClassic != null) return fileClassic.isOpen();

      return false;
    }
  }
예제 #5
0
 private OFileClassic createFile(String fileName) {
   OFileClassic fileClassic = new OFileClassic();
   String path =
       storageLocal
           .getVariableParser()
           .resolveVariables(storageLocal.getStoragePath() + File.separator + fileName);
   fileClassic.init(path, storageLocal.getMode());
   return fileClassic;
 }
예제 #6
0
  public long isOpen(String fileName) throws IOException {
    synchronized (syncObject) {
      initNameIdMapping();

      final Long fileId = nameIdMap.get(fileName);
      if (fileId == null) return -1;

      final OFileClassic fileClassic = files.get(fileId);
      if (fileClassic == null || !fileClassic.isOpen()) return -1;

      return fileId;
    }
  }
예제 #7
0
  private String doDeleteFile(long fileId) throws IOException {
    if (isOpen(fileId)) truncateFile(fileId);

    final OFileClassic fileClassic = files.remove(fileId);

    String name = null;
    if (fileClassic != null) {
      name = fileClassic.getName();

      if (fileClassic.exists()) fileClassic.delete();
    }

    return name;
  }
예제 #8
0
  private void flushPage(long fileId, long pageIndex, ODirectMemoryPointer dataPointer)
      throws IOException {
    if (writeAheadLog != null) {
      OLogSequenceNumber lsn = ODurablePage.getLogSequenceNumberFromPage(dataPointer);
      OLogSequenceNumber flushedLSN = writeAheadLog.getFlushedLSN();
      if (flushedLSN == null || flushedLSN.compareTo(lsn) < 0) writeAheadLog.flush();
    }

    final byte[] content = dataPointer.get(0, pageSize);
    OLongSerializer.INSTANCE.serializeNative(MAGIC_NUMBER, content, 0);

    final int crc32 = calculatePageCrc(content);
    OIntegerSerializer.INSTANCE.serializeNative(crc32, content, OLongSerializer.LONG_SIZE);

    final OFileClassic fileClassic = files.get(fileId);
    fileClassic.write(pageIndex * pageSize, content);

    if (syncOnPageFlush) fileClassic.synch();
  }
  private void validateFileContent(byte version, int k) throws IOException {
    String path =
        storageLocal.getConfiguration().getDirectory() + "/readWriteCacheTest" + k + ".tst";

    OFileClassic fileClassic = new OFileClassic();
    fileClassic.init(path, "r");
    fileClassic.open();

    for (int i = 0; i < PAGE_COUNT; i++) {
      byte[] content = new byte[8];
      fileClassic.read(i * (8 + systemOffset) + systemOffset, content, 8);

      Assert.assertEquals(
          content,
          new byte[] {version, 2, 3, seed, 5, 6, (byte) k, (byte) (i & 0xFF)},
          " i = " + i);
    }
    fileClassic.close();
  }
예제 #10
0
  private OCachePointer cacheFileContent(long fileId, long pageIndex) throws IOException {
    final long startPosition = pageIndex * pageSize;
    final long endPosition = startPosition + pageSize;

    byte[] content = new byte[pageSize];
    OCachePointer dataPointer;
    final OFileClassic fileClassic = files.get(fileId);

    if (fileClassic.getFilledUpTo() >= endPosition) {
      fileClassic.read(startPosition, content, content.length);
      final ODirectMemoryPointer pointer = new ODirectMemoryPointer(content);

      final OLogSequenceNumber storedLSN = ODurablePage.getLogSequenceNumberFromPage(pointer);
      dataPointer = new OCachePointer(pointer, storedLSN);
    } else {
      fileClassic.allocateSpace((int) (endPosition - fileClassic.getFilledUpTo()));

      final ODirectMemoryPointer pointer = new ODirectMemoryPointer(content);
      dataPointer = new OCachePointer(pointer, new OLogSequenceNumber(0, -1));
    }

    return dataPointer;
  }
예제 #11
0
  public OPageDataVerificationError[] checkStoredPages(
      OCommandOutputListener commandOutputListener) {
    final int notificationTimeOut = 5000;
    final List<OPageDataVerificationError> errors = new ArrayList<OPageDataVerificationError>();

    synchronized (syncObject) {
      for (long fileId : files.keySet()) {

        OFileClassic fileClassic = files.get(fileId);

        boolean fileIsCorrect;
        try {

          if (commandOutputListener != null)
            commandOutputListener.onMessage("Flashing file " + fileClassic.getName() + "... ");

          flush(fileId);

          if (commandOutputListener != null)
            commandOutputListener.onMessage(
                "Start verification of content of " + fileClassic.getName() + "file ...");

          long time = System.currentTimeMillis();

          long filledUpTo = fileClassic.getFilledUpTo();
          fileIsCorrect = true;

          for (long pos = 0; pos < filledUpTo; pos += pageSize) {
            boolean checkSumIncorrect = false;
            boolean magicNumberIncorrect = false;

            byte[] data = new byte[pageSize];

            fileClassic.read(pos, data, data.length);

            long magicNumber = OLongSerializer.INSTANCE.deserializeNative(data, 0);

            if (magicNumber != MAGIC_NUMBER) {
              magicNumberIncorrect = true;
              if (commandOutputListener != null)
                commandOutputListener.onMessage(
                    "Error: Magic number for page "
                        + (pos / pageSize)
                        + " in file "
                        + fileClassic.getName()
                        + " does not much !!!");
              fileIsCorrect = false;
            }

            final int storedCRC32 =
                OIntegerSerializer.INSTANCE.deserializeNative(data, OLongSerializer.LONG_SIZE);

            final int calculatedCRC32 = calculatePageCrc(data);
            if (storedCRC32 != calculatedCRC32) {
              checkSumIncorrect = true;
              if (commandOutputListener != null)
                commandOutputListener.onMessage(
                    "Error: Checksum for page "
                        + (pos / pageSize)
                        + " in file "
                        + fileClassic.getName()
                        + " is incorrect !!!");
              fileIsCorrect = false;
            }

            if (magicNumberIncorrect || checkSumIncorrect)
              errors.add(
                  new OPageDataVerificationError(
                      magicNumberIncorrect,
                      checkSumIncorrect,
                      pos / pageSize,
                      fileClassic.getName()));

            if (commandOutputListener != null
                && System.currentTimeMillis() - time > notificationTimeOut) {
              time = notificationTimeOut;
              commandOutputListener.onMessage((pos / pageSize) + " pages were processed ...");
            }
          }
        } catch (IOException ioe) {
          if (commandOutputListener != null)
            commandOutputListener.onMessage(
                "Error: Error during processing of file "
                    + fileClassic.getName()
                    + ". "
                    + ioe.getMessage());

          fileIsCorrect = false;
        }

        if (!fileIsCorrect) {
          if (commandOutputListener != null)
            commandOutputListener.onMessage(
                "Verification of file " + fileClassic.getName() + " is finished with errors.");
        } else {
          if (commandOutputListener != null)
            commandOutputListener.onMessage(
                "Verification of file " + fileClassic.getName() + " is successfully finished.");
        }
      }

      return errors.toArray(new OPageDataVerificationError[errors.size()]);
    }
  }
예제 #12
0
 public void setSoftlyClosed(long fileId, boolean softlyClosed) throws IOException {
   synchronized (syncObject) {
     OFileClassic fileClassic = files.get(fileId);
     if (fileClassic != null && fileClassic.isOpen()) fileClassic.setSoftlyClosed(softlyClosed);
   }
 }
예제 #13
0
 public void forceSyncStoredChanges() throws IOException {
   synchronized (syncObject) {
     for (OFileClassic fileClassic : files.values()) fileClassic.synch();
   }
 }
예제 #14
0
 private void openFile(OFileClassic fileClassic) throws IOException {
   if (fileClassic.exists()) {
     if (!fileClassic.isOpen()) fileClassic.open();
   } else fileClassic.create(-1);
 }