Package org.tmatesoft.hg.internal

Source Code of org.tmatesoft.hg.internal.PathPool

/*
* Copyright (c) 2011-2012 TMate Software Ltd
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* For information on how to redistribute this software under
* the terms of a license other than GNU General Public License
* contact TMate Software at support@hg4j.com
*/
package org.tmatesoft.hg.internal;

import java.lang.ref.SoftReference;
import java.util.WeakHashMap;

import org.tmatesoft.hg.util.Convertor;
import org.tmatesoft.hg.util.Path;
import org.tmatesoft.hg.util.PathRewrite;


/**
* Produces path from strings and caches (weakly) result for reuse
*
* @author Artem Tikhomirov
* @author TMate Software Ltd.
*/
public class PathPool implements Path.Source, Convertor<Path> {
  private final WeakHashMap<CharSequence, SoftReference<Path>> cache;
  private final PathRewrite pathRewrite;
 
  public PathPool(PathRewrite rewrite) {
    pathRewrite = rewrite;
    cache = new WeakHashMap<CharSequence, SoftReference<Path>>();
  }

  /*
   * (non-Javadoc)
   * @see org.tmatesoft.hg.util.Path.Source#path(java.lang.CharSequence)
   */
  public Path path(CharSequence p) {
    if (p instanceof Path) {
      return asPath((Path) p);
    }
    p = pathRewrite.rewrite(p);
    return get(p, true);
  }

  /*
   * (non-Javadoc)
   * @see org.tmatesoft.hg.util.Convertor#mangle(java.lang.Object)
   */
  public Path mangle(Path p) {
    return asPath(p);
  }

  // pipes path object through cache to reuse instance, if possible
  // TODO unify with Pool<Path>
  private Path asPath(Path p) {
    CharSequence s = pathRewrite.rewrite(p.toString());
    // rewrite string, not path to avoid use of Path object as key
    // in case pathRewrite does nothing and returns supplied instance
    //
    Path cached = get(s, false);
    if (cached == null) {
      cache.put(s, new SoftReference<Path>(cached = p));
    }
    return cached;
  }

  // XXX what would be parent of an empty path?
  // Path shall have similar functionality
  public Path parent(Path path) {
    if (path.length() == 0) {
      throw new IllegalArgumentException();
    }
    for (int i = path.length() - 2 /*if path represents a dir, trailing char is slash, skip*/; i >= 0; i--) {
      if (path.charAt(i) == '/') {
        return get(path.subSequence(0, i+1).toString(), true);
      }
    }
    return get("", true);
  }
 
  // invoke when path pool is no longer in use, to ease gc work
  public void clear() {
    cache.clear();
  }

  private Path get(CharSequence p, boolean create) {
    SoftReference<Path> sr = cache.get(p);
    Path path = sr == null ? null : sr.get();
    if (path == null) {
      if (create) {
        path = Path.create(p);
        cache.put(p, new SoftReference<Path>(path));
      } else if (sr != null) {
        // cached path no longer used, clear cache entry - do not wait for RefQueue to step in
        cache.remove(p);
      }
    }
    return path;
  }
}
TOP

Related Classes of org.tmatesoft.hg.internal.PathPool

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.