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

📄 persistentstorage.java

📁 pastry的java实现的2.0b版
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
   *   * @param a The first string   * @param b The second string   * @param max The maximum value to return   * @return The PrefixLength value   */  private int getPrefixLength(String a, String b, int max) {    int i = 0;    for (; (i < a.length() - 1) && (i < b.length() - 1) && (i < max); i++) {      if (a.charAt(i) != b.charAt(i)) {        return i;      }    }    return i;  }  /**   * Returns whether or not the given file is a temporary file.   *   * @param name The name of the file   * @return Whether or not it is temporary   */  private boolean isTemporaryFile(String name) {    return (name.indexOf(".") >= 0);  }  /**   * Returns whether or not the provided file is an acestor of the other file.   *   * @param file The file to check   * @param ancestor The potential ancestor   * @return Whether or not the file is an ancestor   */  private boolean isAncestor(File file, File ancestor) {    while ((file != null) && (!file.equals(ancestor))) {      file = file.getParentFile();    }    return (file != null);  }  /**   * Gets the file for a certain id from the disk   *   * @param id the id to get a file for   * @return File the file for the id   * @exception IOException DESCRIBE THE EXCEPTION   */  private File getFile(Id id) throws IOException {    File dir = getDirectoryForId(id);    String name = id.toStringFull().substring(getPrefix(dir).length());    if (name.equals("")) {      name = ZERO_LENGTH_NAME;    }    // check for ! directory    File file = new File(dir, name);    if (file.exists() && file.isDirectory()) {      file = new File(file, ZERO_LENGTH_NAME);    }    return file;  }  /**   * Gets the directory an id should be stored in   *   * @param id the string representation of the id   * @return File the directory that should contain an id   * @exception IOException DESCRIBE THE EXCEPTION   */  private File getDirectoryForId(Id id) throws IOException {    return getDirectoryForName(id.toStringFull());  }  /**   * Gets the directory a given file should be stored in   *   * @param name The name of the file   * @return File the directory that should contain an id   * @exception IOException DESCRIBE THE EXCEPTION   */  private File getDirectoryForName(String name) throws IOException {    return getDirectoryForName(name, appDirectory);  }  /**   * Gets the best directory for the given name   *   * @param name The name to serach for   * @param dir The directory to start at   * @return The directory the name should be stored in   * @exception IOException DESCRIBE THE EXCEPTION   */  private File getDirectoryForName(String name, File dir) throws IOException {    File[] subDirs = (File[]) directories.get(dir);    if (subDirs.length == 0) {      return dir;    } else {      for (int i = 0; i < subDirs.length; i++) {        if (name.startsWith(subDirs[i].getName())) {          return getDirectoryForName(name.substring(subDirs[i].getName().length()), subDirs[i]);        } else if ((name.length() == 0) && subDirs[i].getName().equals(ZERO_LENGTH_NAME)) {          return getDirectoryForName(name, subDirs[i]);        }      }      /*       *  here, we must create the appropriate directory       */      if ((name.length() >= subDirs[0].getName().length()) || ((name.length() == 0) && (subDirs[0].getName().length() == 1))) {        File newDir = new File(dir, (name.length() == 0 ? ZERO_LENGTH_NAME : name.substring(0, subDirs[0].getName().length())));        if (logger.level <= Logger.FINE) {          logger.log("Necessarily creating dir " + newDir.getName());        }        createDirectory(newDir);        this.directories.put(dir, append(subDirs, newDir));        this.directories.put(newDir, new File[0]);        /*         *  finally, we must check if this caused too many dirs in one dir.  If so, we         *  simply rerun the algorithm which will reflect the new dir         */        if (checkDirectory(dir)) {          return getDirectoryForName(name, dir);        } else {          return newDir;        }      } else {        /*         *  here, we have to handle a wierd case where the filename is less than that of         *  an existing directory.  To handle this, we pretend like we're doing a directory         *  split, and create new subdirs so we can accomidate everything.         */        String[] dirs = new String[subDirs.length + 1];        for (int i = 0; i < subDirs.length; i++) {          dirs[i] = subDirs[i].getName();        }        dirs[subDirs.length] = (name.length() == 0 ? ZERO_LENGTH_NAME : name);        /*         *  now reformat the directory, creating an entry for this name         */        reformatDirectory(dir, getDirectories(dirs));        /*         *  and finally, recurse, which should find a directory for this name         */        return getDirectoryForName(name, dir);      }    }  }  /**   * Internal method which returns the postfix for a given id   *   * @param id The id to return the postfix for   * @param file The directory the id will be stored in   * @return The postfix   */  private String getPostfix(Id id, File file) {    return id.toStringFull().substring(getPrefix(file).length());  }  /**   * Internal method which returns the prefix of a given directory   *   * @param file The directory to return the prefix for   * @return The prefix   */  private String getPrefix(File file) {    if (prefixes.get(file) != null) {      return (String) prefixes.get(file);    }    StringBuffer buffer = new StringBuffer();    while (!file.equals(appDirectory)) {      buffer.insert(0, file.getName().replaceAll(ZERO_LENGTH_NAME, ""));      file = file.getParentFile();    }    prefixes.put(file, buffer.toString());    return getPrefix(file);  }  /**   * Returns whether or not the given filename represents a stored file   *   * @param name The name of the file   * @param parent DESCRIBE THE PARAMETER   * @return int the number of files   */  private boolean isFile(File parent, String name) {//    return (((getPrefix(parent).length() + name.length()) >= factory.getIdToStringLength()) && (! name.equals(METADATA_FILENAME)));    return ((!new File(parent, name).isDirectory()) && (!name.equals(METADATA_FILENAME)));  }  /**   * Returns whether or not the given filename represents a directory   *   * @param name The name of the file   * @param parent DESCRIBE THE PARAMETER   * @return int the number of files   */  private boolean isDirectory(File parent, String name) {//    return (((getPrefix(parent).length() + name.length()) < factory.getIdToStringLength()) && (new File(parent, name)).isDirectory());    return (new File(parent, name)).isDirectory();  }  /**   * Utility function which returns the range of keys which a directory   * corresponds to.   *   * @param dir The directory   * @return The RangeForDirectory value   */  protected IdRange getRangeForDirectory(File dir) {    String result = "";    while (!dir.equals(appDirectory)) {      result = dir.getName() + result;      dir = dir.getParentFile();    }    return factory.buildIdRangeFromPrefix(result);  }  /**   * gets the root directory that the persistence Manager uses   *   * @return String the directory for the root   */  public String getRoot() {    return rootDir;  }  /**   * gets the amount of storage that the persistence Manager uses   *   * @return int the amount of storage in bytes allocated for use   */  public long getStorageSize() {    if (storageSize > 0) {      return storageSize;    } else {      return Long.MAX_VALUE;    }  }  /**   * Gets the amound of space currently being used on disk   *   * @return long the amount of space being used   */  private long getUsedSpace() {    return usedSize;  }  /**   * Gets the name of this instance   *   * @return String the name of the instance   */  public String getName() {    return name;  }  /**   * Method which allows the persistence root to schedle an event which will   * tell it to sync the metadata cached. Should be called exactly once after   * the persistence root is created.   *   * @param timer The timer to use to schedule the events   */  public void setTimer(rice.selector.Timer timer) {    if (index) {      timer.scheduleAtFixedRate(        new rice.selector.TimerTask() {          public String toString() {            return "persistence dirty purge enqueue";          }          public void run() {            environment.getProcessor().processBlockingIO(              new WorkRequest(new ListenerContinuation("Enqueue of writeMetadataFile", environment), environment.getSelectorManager()) {                public String toString() {                  return "persistence dirty purge";                }                public Object doWork() throws Exception {                  writeDirty();                  return Boolean.TRUE;                }              });          }        }, environment.getRandomSource().nextInt(METADATA_SYNC_TIME), METADATA_SYNC_TIME);    }  }  /**   * Updates the metadata stored under the given key to be the provided value.   * As this may require a disk access, the requestor must also provide a   * continuation to return the result to.   *   * @param id The id for the metadata   * @param metadata The metadata to store   * @param c The command to run once the operation is complete   */  public void setMetadata(final Id id, final Serializable metadata, Continuation c) {    printStats();    if (!exists(id)) {      c.receiveResult(new Boolean(false));    } else {      environment.getProcessor().processBlockingIO(        new WorkRequest(c, environment.getSelectorManager()) {          public String toString() {            return "setMetadata " + id;          }          public Object doWork() throws Exception {            synchronized (statLock) {              numMetadataWrites++;            }            if (logger.level <= Logger.FINER) {              logger.log("COUNT: Updating metadata for " + id.toStringFull() + " in " + name);            }            /*             *  write the metadata to the file             */            File objFile = getFile(id);            writeMetadata(objFile, metadata);            /*             *  then update our cache             */            if (index) {              synchronized (PersistentStorage.this.metadata) {                PersistentStorage.this.metadata.put(id, metadata);                dirty.add(objFile.getParentFile());              }            }            return Boolean.TRUE;          }        });    }  }  /**   * @param dir The new Root value   * @return DESCRIBE THE RETURN VALUE   */  /*   *  Functions for Configuration Management   */  /**   * @param dir The new Root value   * @return DESCRIBE THE RETURN VALUE   */  /**   * Sets the root directory that the persistence Manager uses   *   * @param dir the String representing the directory to use   * @return boolean, true if the operation suceeds false if it doesn't   */  public boolean setRoot(String dir) {    /*     *  We should do something logical here to the existing files     */    rootDir = dir;    return true;  }  /**   * Sets the amount of storage that the persistence Manager uses   *   * @param size the amount of storage available to use in bytes   * @return boolean, true if the operation suceeds false if it doesn't   */  public boolean setStorageSize(long size) {    if (storageSize <= size) {      storageSize = size;      return true;    } else if (size > usedSize) {      storageSize = size;      return true;    } else {      return false;    }  }  /**   * DESCRIBE THE METHOD   */  private void printStats() {    synchronized (statLock) {      long now = environment.getTimeSource().currentTimeMillis();      if ((statsLastWritten / statsWriteInterval) != (now / statsWriteInterval)) {        if (logger.level <= Logger.INFO) {          logger.log("@L.PE name=" + name + " interval=" + statsLastWritten + "-" + now);        }        statsLastWritten = now;        if (logger.level <= Logger.INFO) {          logger.log("@L.PE   objsTotal=" + (index ? "" + metadata.keySet().size() : "?") + " objsBytesTotal=" + getTotalSize());        }        if (logger.level <= Logger.INFO) {          logger.log("@L.PE   numWrites=" + numWrites + " numReads=" + numReads + " numDeletes=" + numDeletes);        }        if (logger.level <= Logger.INFO) {          logger.log("@L.PE   numMetadataWrites=" + numMetadataWrites + " numRenames=" + numRenames);        }      }    }  }

⌨️ 快捷键说明

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