예제 #1
0
 private static void setCurrentVersion() {
   myRecords.putInt(HEADER_VERSION_OFFSET, VERSION);
   myRecords.putLong(HEADER_TIMESTAMP_OFFSET, System.currentTimeMillis());
   myAttributes.setVersion(VERSION);
   myContents.setVersion(VERSION);
   myRecords.putInt(HEADER_CONNECTION_STATUS_OFFSET, SAFELY_CLOSED_MAGIC);
 }
예제 #2
0
 private static void markClean() {
   if (myDirty) {
     myDirty = false;
     myRecords.putInt(
         HEADER_CONNECTION_STATUS_OFFSET, myCorrupted ? CORRUPTED_MAGIC : SAFELY_CLOSED_MAGIC);
   }
 }
예제 #3
0
    private static void closeFiles() throws IOException {
      if (myFlushingFuture != null) {
        myFlushingFuture.cancel(false);
        myFlushingFuture = null;
      }

      if (myNames != null) {
        myNames.close();
        myNames = null;
      }

      if (myAttributes != null) {
        Disposer.dispose(myAttributes);
        myAttributes = null;
      }

      if (myContents != null) {
        Disposer.dispose(myContents);
        myContents = null;
      }

      if (myRecords != null) {
        markClean();
        myRecords.close();
        myRecords = null;
      }
      ourInitialized = false;
    }
예제 #4
0
    private static int getVersion() {
      final int recordsVersion = myRecords.getInt(HEADER_VERSION_OFFSET);
      if (myAttributes.getVersion() != recordsVersion || myContents.getVersion() != recordsVersion)
        return -1;

      return recordsVersion;
    }
예제 #5
0
 public static boolean isDirty() {
   return myDirty
       || myNames.isDirty()
       || myAttributes.isDirty()
       || myContents.isDirty()
       || myRecords.isDirty();
 }
예제 #6
0
 public static void force() {
   try {
     w.lock();
     if (myRecords != null) {
       markClean();
     }
     if (myNames != null) {
       myNames.force();
       myAttributes.force();
       myContents.force();
       myRecords.force();
     }
   } finally {
     w.unlock();
   }
 }
예제 #7
0
    public static void flushSome() {
      if (!isDirty() || HeavyProcessLatch.INSTANCE.isRunning()) return;

      try {
        w.lock();
        if (myFlushingFuture == null) {
          return; // avoid NPE when close has already taken place
        }
        myNames.force();

        final boolean attribsFlushed = myAttributes.flushSome();
        final boolean contentsFlushed = myContents.flushSome();
        if (attribsFlushed && contentsFlushed) {
          markClean();
          myRecords.force();
        }
      } finally {
        w.unlock();
      }
    }
예제 #8
0
 public static void cleanRecord(final int id) {
   myRecords.put(id * RECORD_SIZE, ZEROES, 0, RECORD_SIZE);
 }
예제 #9
0
 public static long getTimestamp() {
   return myRecords.getLong(HEADER_TIMESTAMP_OFFSET);
 }
예제 #10
0
 private static void markDirty() {
   if (!myDirty) {
     myDirty = true;
     myRecords.putInt(HEADER_CONNECTION_STATUS_OFFSET, CONNECTED_MAGIC);
   }
 }
예제 #11
0
    private static void init() {
      final File basePath = basePath();
      basePath.mkdirs();

      final File namesFile = new File(basePath, "names.dat");
      final File attributesFile = new File(basePath, "attrib.dat");
      final File contentsFile = new File(basePath, "content.dat");
      final File recordsFile = new File(basePath, "records.dat");

      if (!namesFile.exists()) {
        invalidateIndex();
      }

      try {
        if (getCorruptionMarkerFile().exists()) {
          invalidateIndex();
          throw new IOException("Corruption marker file found");
        }

        PagedFileStorage.StorageLockContext storageLockContext =
            new PagedFileStorage.StorageLock(false).myDefaultStorageLockContext;
        myNames = new PersistentStringEnumerator(namesFile, storageLockContext);
        myAttributes = new Storage(attributesFile.getCanonicalPath(), REASONABLY_SMALL);
        myContents =
            new RefCountingStorage(
                contentsFile.getCanonicalPath(),
                CapacityAllocationPolicy
                    .FIVE_PERCENT_FOR_GROWTH); // sources usually zipped with 4x ratio
        boolean aligned = PagedFileStorage.BUFFER_SIZE % RECORD_SIZE == 0;
        assert aligned; // for performance
        myRecords =
            new ResizeableMappedFile(
                recordsFile, 20 * 1024, storageLockContext, PagedFileStorage.BUFFER_SIZE, aligned);

        if (myRecords.length() == 0) {
          cleanRecord(0); // Clean header
          cleanRecord(1); // Create root record
          setCurrentVersion();
        }

        if (getVersion() != VERSION) {
          throw new IOException("FS repository version mismatch");
        }

        if (myRecords.getInt(HEADER_CONNECTION_STATUS_OFFSET) != SAFELY_CLOSED_MAGIC) {
          throw new IOException("FS repository wasn't safely shut down");
        }
        markDirty();
        scanFreeRecords();
      } catch (Exception e) { // IOException, IllegalArgumentException
        LOG.info(
            "Filesystem storage is corrupted or does not exist. [Re]Building. Reason: "
                + e.getMessage());
        try {
          closeFiles();

          boolean deleted = FileUtil.delete(getCorruptionMarkerFile());
          deleted &= deleteWithSubordinates(namesFile);
          deleted &= AbstractStorage.deleteFiles(attributesFile.getCanonicalPath());
          deleted &= AbstractStorage.deleteFiles(contentsFile.getCanonicalPath());
          deleted &= deleteWithSubordinates(recordsFile);

          if (!deleted) {
            throw new IOException("Cannot delete filesystem storage files");
          }
        } catch (final IOException e1) {
          final Runnable warnAndShutdown =
              new Runnable() {
                @Override
                public void run() {
                  if (ApplicationManager.getApplication().isUnitTestMode()) {
                    //noinspection CallToPrintStackTrace
                    e1.printStackTrace();
                  } else {
                    final String message =
                        "Files in "
                            + basePath.getPath()
                            + " are locked.\n"
                            + ApplicationNamesInfo.getInstance().getProductName()
                            + " will not be able to start up.";
                    if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
                      JOptionPane.showMessageDialog(
                          JOptionPane.getRootFrame(),
                          message,
                          "Fatal Error",
                          JOptionPane.ERROR_MESSAGE);
                    } else {
                      //noinspection UseOfSystemOutOrSystemErr
                      System.err.println(message);
                    }
                  }
                  Runtime.getRuntime().halt(1);
                }
              };

          if (EventQueue.isDispatchThread()) {
            warnAndShutdown.run();
          } else {
            //noinspection SSBasedInspection
            SwingUtilities.invokeLater(warnAndShutdown);
          }

          throw new RuntimeException("Can't rebuild filesystem storage ", e1);
        }

        init();
      }
    }