⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 persistentstorage.java

📁 pastry的java实现的2.0b版
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
      /*       *  mark this directory for metadata syncing       */      if (index) {        dirty.add(dirs[i]);      }    }    /*     *  add the list of directories to the map     */    directories.put(dir, dirs);    /*     *  last, move the files into the correct directory     */    File[] files = dir.listFiles(new FileFilter());    for (int i = 0; i < files.length; i++) {      for (int j = 0; j < dirs.length; j++) {        if (files[i].getName().startsWith(dirs[j].getName())) {          if (logger.level <= Logger.FINEST) {            logger.log("Renaming file " + files[i] + " to " + new File(dirs[j], files[i].getName().substring(dirs[j].getName().length())));          }          renameFile(files[i], new File(dirs[j], files[i].getName().substring(dirs[j].getName().length())));          break;        }      }    }    /*     *  and remove the metadata file     */    deleteFile(new File(dir, METADATA_FILENAME));    if (logger.level <= Logger.FINE) {      logger.log("Done expanding directory " + dir);    }  }  /**   * Takes a file and moves it to the correct directory this is used in   * cojunction with expand to move files to their correct subdirectories below   * the expanded directory   *   * @param parent DESCRIBE THE PARAMETER   * @param name DESCRIBE THE PARAMETER   * @exception IOException DESCRIBE THE EXCEPTION   */  private void moveFileToCorrectDirectory(File parent, String name) throws IOException {    File file = new File(parent, name);    Id id = readKeyFromFile(file);    File dest = getDirectoryForId(id);    /*     *  if it's in the wrong directory, then move it and resolve the conflict if necessary     */    if (!dest.equals(parent)) {      if (logger.level <= Logger.FINE) {        logger.log("moving file " + file + " to correct directory " + dest + " from " + parent);      }      File other = new File(dest, id.toStringFull().substring(getPrefix(dest).length()));      resolveConflict(file, other, other);      checkDirectory(dest);    }  }  /**   * Method which recursively flushes a directory hierarchy, removing all data.   * Be careful!   *   * @param dir The directory to flush   * @exception IOException DESCRIBE THE EXCEPTION   */  private void flushDirectory(File dir) throws IOException {    if (logger.level <= Logger.FINE) {      logger.log("Flushing file " + dir);    }    if (!dir.isDirectory()) {      Id id = readKey(dir);      /*       *  remove id from stored list       */      if (index) {        synchronized (metadata) {          metadata.remove(id);        }      }      /*       *  record the space collected and delete the file       */      decreaseUsedSpace(dir.length());      deleteFile(dir);    } else {      File[] dirs = dir.listFiles();      /*       *  remove all subdirectories       */      for (int i = 0; i < dirs.length; i++) {        flushDirectory(dirs[i]);        /*         *  update the metadata         */        directories.remove(dirs[i]);        prefixes.remove(dirs[i]);        /*         *  delete the dir         */        deleteFile(dirs[i]);      }    }  }  /**   * Generates a new file name to assign for a given id   *   * @param id DESCRIBE THE PARAMETER   * @return String the new File name This method will return the hashcode of   *      the object used as the id unless there is a collision, in which case   *      it will return a random number Since this mapping is only needed once   *      it does not matter what number is used to generate the filename, the   *      hashcode is the first try for effeciency.   * @exception IOException DESCRIBE THE EXCEPTION   */  private File makeTemporaryFile(Id id) throws IOException {    File directory = getDirectoryForId(id);    File file = new File(directory, id.toStringFull().substring(getPrefix(directory).length()) + "." + environment.getRandomSource().nextInt() % 100);    while (file.exists()) {      file = new File(directory, id.toStringFull().substring(getPrefix(directory).length()) + "." + environment.getRandomSource().nextInt() % 100);    }    return file;  }  /**   * Method which the given file to the list of files   *   * @param file The file   * @param files DESCRIBE THE PARAMETER   * @return The new list   */  private File[] append(File[] files, File file) {    File[] result = new File[files.length + 1];    for (int i = 0; i < files.length; i++) {      result[i] = files[i];    }    result[files.length] = file;    return result;  }  /**   * Gets the number of subdirectories in directory   *   * @param dir the directory to check   * @return int the number of directories   */  private int numDirectoriesDir(File dir) {    return dir.listFiles(new DirectoryFilter()).length;  }  /**   * Gets the number of files in directory (excluding directories)   *   * @param dir the directory to check   * @return int the number of files   */  private int numFilesDir(File dir) {    return dir.listFiles(new FileFilter()).length;  }  /**   * Returns whether a directory contains subdirectories   *   * @param dir the directory to check   * @return boolean whether directory contains subdirectories   */  private boolean containsDir(File dir) {    return (dir.listFiles(new DirectoryFilter()).length != 0);  }  /**   */  /*   *  Helper functions for Metadata Storage   */  /**   */  /**   * Function which writes out all of the dirty metadata files and marks them as   * clean.   */  protected void writeDirty() {    File[] files = (File[]) dirty.toArray(new File[0]);    for (int i = 0; i < files.length; i++) {      HashMap map = new HashMap();      IdRange range = getRangeForDirectory(files[i]);      Iterator keys = null;      if (range.getCCWId().compareTo(range.getCWId()) <= 0) {        keys = metadata.keySubMap(range.getCCWId(), range.getCWId()).keySet().iterator();      } else {        keys = metadata.keyTailMap(range.getCCWId()).keySet().iterator();      }      while (keys.hasNext()) {        Id next = (Id) keys.next();        map.put(next, metadata.get(next));      }      try {        writeMetadataFile(files[i], map);        synchronized (metadata) {          dirty.remove(files[i]);        }      } catch (FileNotFoundException f) {        try {          synchronized (metadata) {            dirty.remove(files[i]);          }          if (logger.level <= Logger.WARNING) {            logger.logException("ERROR: Could not find directory while writing out metadata in '" + files[i].getCanonicalPath() + "' - removing from dirty list and continuing!", f);          }        } catch (IOException g) {          if (logger.level <= Logger.SEVERE) {            logger.logException("PANIC: Got IOException " + g + " trying to detail FNF exception " + f + " while writing out file " + files[i], g);          }        }      } catch (IOException e) {        try {          if (logger.level <= Logger.WARNING) {            logger.logException(              "ERROR: Got error " + e + " while writing out metadata in '" + files[i].getCanonicalPath() + "' - aborting!", e);          }        } catch (IOException f) {          if (logger.level <= Logger.SEVERE) {            logger.logException("PANIC: Got IOException " + f + " trying to detail exception " + e + " while writing out file " + files[i], f);          }        }      }    }  }  /**   * Utility function which reads the metadata file off of disk and stores the   * result into the memory cache.   *   * @param file The directory to read the metadata file for   * @return DESCRIBE THE RETURN VALUE   * @exception IOException DESCRIBE THE EXCEPTION   */  private long readMetadataFile(File file) throws IOException {    File metadata = new File(file, METADATA_FILENAME);    if (!metadata.exists()) {      return -1L;    }    FileInputStream fin = null;    try {      fin = new FileInputStream(metadata);      ObjectInputStream objin = new ObjectInputStream(new BufferedInputStream(fin));      IdRange range = getRangeForDirectory(file);      try {        HashMap map = (HashMap) objin.readObject();        Iterator keys = map.keySet().iterator();        while (keys.hasNext()) {          Id id = (Id) keys.next();          if ((range.containsId(id)) && (new File(file, id.toStringFull().substring(getPrefix(file).length())).exists())) {            this.metadata.put(id, map.get(id));          } else {            dirty.add(file);          }        }        return metadata.lastModified();      } catch (ClassNotFoundException e) {        if (logger.level <= Logger.WARNING) {          logger.logException("ERROR: Got exception " + e + " while reading metadata file " + metadata + " - rebuilding file", e);        }        deleteFile(metadata);        return 0L;      } catch (IOException e) {        if (logger.level <= Logger.WARNING) {          logger.logException("ERROR: Got exception " + e + " while reading metadata file " + metadata + " - rebuilding file", e);        }        deleteFile(metadata);        return 0L;      }    } finally {      fin.close();    }  }  /**   * Reads in the metadata from the provided file, or returns null if no   * metadata was found   *   * @param file The file which should be read for the metadata   * @return DESCRIBE THE RETURN VALUE   * @exception IOException DESCRIBE THE EXCEPTION   */  private Serializable readMetadata(File file) throws IOException {    if (file.length() < 32) {      return null;    }    RandomAccessFile ras = null;    try {      ras = new RandomAccessFile(file, "r");      ras.seek(file.length() - 32);      if (ras.readLong() != PERSISTENCE_MAGIC_NUMBER) {        return null;      } else if (ras.readLong() != PERSISTENCE_VERSION_2) {        if (logger.level <= Logger.WARNING) {          logger.log("Persistence version did not match - exiting!");        }        return null;      } else if (ras.readLong() > PERSISTENCE_REVISION_2_1) {        if (logger.level <= Logger.WARNING) {          logger.log("Persistence revision did not match - exiting!");        }        return null;      }      long length = ras.readLong();      ras.seek(file.length() - 32 - length);      FileInputStream fis = null;      try {        fis = new FileInputStream(ras.getFD());        ObjectInputStream objin = new XMLObjectInputStream(new BufferedInputStream(new GZIPInputStream(fis)));        try {          return (Serializable) objin.readObject();        } catch (ClassNotFoundException e) {          throw new IOException(e.getMessage());        }      } finally {        fis.close();      }    } finally {      ras.close();    }  }  /**   * Abstract over reading a single key from a file using Java serialization.   *   * @param file The file to create the key from.   * @return The key that was read in   */  private Id readKey(File file) {    String s = getPrefix(file.getParentFile()) + file.getName().replaceAll(ZERO_LENGTH_NAME, "");    if (s.indexOf(".") >= 0) {      return factory.buildIdFromToString(s.toCharArray(), 0, s.indexOf("."));    } else {      return factory.buildIdFromToString(s.toCharArray(), 0, s.length());    }  }  /**   * Abstract over reading a single key from a file using Java serialization.   *   * @param file The file to create the key from.   * @return The key that was read in   * @exception IOException DESCRIBE THE EXCEPTION   */  private Id readKeyFromFile(File file) throws IOException {    return (Id) readObject(file, 0);  }  /**   * Increases the amount of storage recorded as used   *   * @param i DESCRIBE THE PARAMETER   */  private void increaseUsedSpace(long i) {    usedSize = usedSize + i;  }  /**   * decreases the amount of storage recorded as used   *   * @param i DESCRIBE THE PARAMETER   */  private void decreaseUsedSpace(long i) {    usedSize = usedSize - i;  }  /**   * Returns the length of a file in bytes   *   * @param file file whose length to get   * @return The FileLength value   */  private static long getFileLength(File file) {    return (((file != null) && file.exists()) ? f

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -