예제 #1
0
    void scan(String prefix) {
      if (ALL.equals(prefix)) {
        scanOne(HEAD);
        scanTree(R_REFS, refsDir);

        // If any entries remain, they are deleted, drop them.
        if (newLoose == null && curIdx < curLoose.size()) newLoose = curLoose.copy(curIdx);

      } else if (prefix.startsWith(R_REFS) && prefix.endsWith("/")) { // $NON-NLS-1$
        curIdx = -(curLoose.find(prefix) + 1);
        File dir = new File(refsDir, prefix.substring(R_REFS.length()));
        scanTree(prefix, dir);

        // Skip over entries still within the prefix; these have
        // been removed from the directory.
        while (curIdx < curLoose.size()) {
          if (!curLoose.get(curIdx).getName().startsWith(prefix)) break;
          if (newLoose == null) newLoose = curLoose.copy(curIdx);
          curIdx++;
        }

        // Keep any entries outside of the prefix space, we
        // do not know anything about their status.
        if (newLoose != null) {
          while (curIdx < curLoose.size()) newLoose.add(curLoose.get(curIdx++));
        }
      }
    }
예제 #2
0
  @Override
  public Map<String, Ref> getRefs(String prefix) throws IOException {
    final RefList<LooseRef> oldLoose = looseRefs.get();
    LooseScanner scan = new LooseScanner(oldLoose);
    scan.scan(prefix);
    final RefList<Ref> packed = getPackedRefs();

    RefList<LooseRef> loose;
    if (scan.newLoose != null) {
      scan.newLoose.sort();
      loose = scan.newLoose.toRefList();
      if (looseRefs.compareAndSet(oldLoose, loose)) modCnt.incrementAndGet();
    } else loose = oldLoose;
    fireRefsChanged();

    RefList.Builder<Ref> symbolic = scan.symbolic;
    for (int idx = 0; idx < symbolic.size(); ) {
      final Ref symbolicRef = symbolic.get(idx);
      final Ref resolvedRef = resolve(symbolicRef, 0, prefix, loose, packed);
      if (resolvedRef != null && resolvedRef.getObjectId() != null) {
        symbolic.set(idx, resolvedRef);
        idx++;
      } 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.
        symbolic.remove(idx);
        final int toRemove = loose.find(symbolicRef.getName());
        if (0 <= toRemove) loose = loose.remove(toRemove);
      }
    }
    symbolic.sort();

    return new RefMap(prefix, packed, upcast(loose), symbolic.toRefList());
  }
예제 #3
0
    private void scanOne(String name) {
      LooseRef cur;

      if (curIdx < curLoose.size()) {
        do {
          cur = curLoose.get(curIdx);
          int cmp = RefComparator.compareTo(cur, name);
          if (cmp < 0) {
            // Reference is not loose anymore, its been deleted.
            // Skip the name in the new result list.
            if (newLoose == null) newLoose = curLoose.copy(curIdx);
            curIdx++;
            cur = null;
            continue;
          }

          if (cmp > 0) // Newly discovered loose reference.
          cur = null;
          break;
        } while (curIdx < curLoose.size());
      } else cur = null; // Newly discovered loose reference.

      LooseRef n;
      try {
        n = scanRef(cur, name);
      } catch (IOException notValid) {
        n = null;
      }

      if (n != null) {
        if (cur != n && newLoose == null) newLoose = curLoose.copy(curIdx);
        if (newLoose != null) newLoose.add(n);
        if (n.isSymbolic()) symbolic.add(n);
      } else if (cur != null) {
        // Tragically, this file is no longer a loose reference.
        // Kill our cached entry of it.
        if (newLoose == null) newLoose = curLoose.copy(curIdx);
      }

      if (cur != null) curIdx++;
    }
예제 #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);
  }
예제 #6
0
  private RefList<Ref> parsePackedRefs(final BufferedReader br) throws IOException {
    RefList.Builder<Ref> all = new RefList.Builder<Ref>();
    Ref last = null;
    boolean peeled = false;
    boolean needSort = false;

    String p;
    while ((p = br.readLine()) != null) {
      if (p.charAt(0) == '#') {
        if (p.startsWith(PACKED_REFS_HEADER)) {
          p = p.substring(PACKED_REFS_HEADER.length());
          peeled = p.contains(PACKED_REFS_PEELED);
        }
        continue;
      }

      if (p.charAt(0) == '^') {
        if (last == null) throw new IOException(JGitText.get().peeledLineBeforeRef);

        ObjectId id = ObjectId.fromString(p.substring(1));
        last = new ObjectIdRef.PeeledTag(PACKED, last.getName(), last.getObjectId(), id);
        all.set(all.size() - 1, last);
        continue;
      }

      int sp = p.indexOf(' ');
      if (sp < 0) {
        throw new IOException(
            MessageFormat.format(
                JGitText.get().packedRefsCorruptionDetected, packedRefsFile.getAbsolutePath()));
      }
      ObjectId id = ObjectId.fromString(p.substring(0, sp));
      String name = copy(p, sp + 1, p.length());
      ObjectIdRef cur;
      if (peeled) cur = new ObjectIdRef.PeeledNonTag(PACKED, name, id);
      else cur = new ObjectIdRef.Unpeeled(PACKED, name, id);
      if (last != null && RefComparator.compareTo(last, cur) > 0) needSort = true;
      all.add(cur);
      last = cur;
    }

    if (needSort) all.sort();
    return all.toRefList();
  }