コード例 #1
0
  private DhtRef resolve(DhtRef ref, int depth, RefList<DhtRef> loose) throws IOException {
    if (!ref.isSymbolic()) return ref;

    DhtRef dst = (DhtRef) ref.getTarget();

    if (MAX_SYMBOLIC_REF_DEPTH <= depth) return null; // claim it doesn't exist

    dst = loose.get(dst.getName());
    if (dst == null) return ref;

    dst = resolve(dst, depth + 1, loose);
    if (dst == null) return null;

    return new DhtSymbolicRef(ref.getName(), dst, ((DhtSymbolicRef) ref).getRefData());
  }
コード例 #2
0
  void stored(String refName, RefData newData) {
    DhtRef ref = fromData(refName, newData);
    RefCache oldCache, newCache;
    do {
      oldCache = cache.get();
      if (oldCache == null) return;

      RefList<DhtRef> ids = oldCache.ids.put(ref);
      RefList<DhtRef> sym = oldCache.sym;

      if (ref.isSymbolic()) {
        sym = sym.put(ref);
      } else {
        int p = sym.find(refName);
        if (0 <= p) sym = sym.remove(p);
      }

      newCache = new RefCache(ids, sym, oldCache.hints);
    } while (!cache.compareAndSet(oldCache, newCache));
  }
コード例 #3
0
  @Override
  public DhtRefUpdate newUpdate(String refName, boolean detach) throws IOException {
    boolean detachingSymbolicRef = false;
    DhtRef ref = getOneRef(refName);
    if (ref == null) ref = new DhtObjectIdRef(refName, NONE);
    else detachingSymbolicRef = detach && ref.isSymbolic();

    if (detachingSymbolicRef) {
      RefData src = ((DhtRef) ref.getLeaf()).getRefData();
      RefData.Builder b = RefData.newBuilder(ref.getRefData());
      b.clearSymref();
      b.setTarget(src.getTarget());
      ref = new DhtObjectIdRef(refName, b.build());
    }

    RepositoryKey repo = repository.getRepositoryKey();
    DhtRefUpdate update = new DhtRefUpdate(this, repo, db, ref);
    if (detachingSymbolicRef) update.setDetachingSymbolicRef();
    return update;
  }
コード例 #4
0
  @Override
  public Map<String, Ref> getRefs(String prefix) throws IOException {
    RefCache curr = readRefs();
    RefList<DhtRef> packed = RefList.emptyList();
    RefList<DhtRef> loose = curr.ids;
    RefList.Builder<DhtRef> sym = new RefList.Builder<DhtRef>(curr.sym.size());

    for (int idx = 0; idx < curr.sym.size(); idx++) {
      DhtRef ref = curr.sym.get(idx);
      String name = ref.getName();
      ref = resolve(ref, 0, loose);
      if (ref != null && ref.getObjectId() != null) {
        sym.add(ref);
      } else {
        // A broken symbolic reference, we have to drop it from the
        // collections the client is about to receive. Should be a
        // rare occurrence so pay a copy penalty.
        int toRemove = loose.find(name);
        if (0 <= toRemove) loose = loose.remove(toRemove);
      }
    }

    return new RefMap(prefix, packed, loose, sym.toRefList());
  }
コード例 #5
0
  private RefCache read() throws DhtException, TimeoutException {
    RefList.Builder<DhtRef> id = new RefList.Builder<DhtRef>();
    RefList.Builder<DhtRef> sym = new RefList.Builder<DhtRef>();
    ObjectIdSubclassMap<IdWithChunk> hints = new ObjectIdSubclassMap<IdWithChunk>();

    for (Map.Entry<RefKey, RefData> e : scan()) {
      DhtRef ref = fromData(e.getKey().getName(), e.getValue());

      if (ref.isSymbolic()) sym.add(ref);
      id.add(ref);

      if (ref.getObjectId() instanceof IdWithChunk && !hints.contains(ref.getObjectId()))
        hints.add((IdWithChunk) ref.getObjectId());
      if (ref.getPeeledObjectId() instanceof IdWithChunk
          && !hints.contains(ref.getPeeledObjectId()))
        hints.add((IdWithChunk) ref.getPeeledObjectId());
    }

    id.sort();
    sym.sort();

    return new RefCache(id.toRefList(), sym.toRefList(), hints);
  }