@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()); }
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); }
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(); }
@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()); }