/** {@inheritDoc} */ @Override public void flush() throws IOException { if (packDsc == null) return; if (packOut == null) throw new IOException(); byte[] packHash = packOut.writePackFooter(); packDsc.addFileExt(PACK); packDsc.setFileSize(PACK, packOut.getCount()); packOut.close(); packOut = null; sortObjectsById(); PackIndex index = writePackIndex(packDsc, packHash, objectList); db.commitPack(Collections.singletonList(packDsc), null); rollback = false; DfsPackFile p = new DfsPackFile(cache, packDsc); if (index != null) p.setPackIndex(index); db.addPack(p); clear(); }
/** {@inheritDoc} */ @Override public void scanForRepoChanges() throws IOException { getRefDatabase().refresh(); getObjectDatabase().clearCache(); }
/** * Commit a pack and index pair that was written to the DFS. * <p> * Committing the pack/index pair makes them visible to readers. The JGit * DFS code always writes the pack, then the index. This allows a simple * commit process to do nothing if readers always look for both files to * exist and the DFS performs atomic creation of the file (e.g. stream to a * temporary file and rename to target on close). * <p> * During pack compaction or GC the new pack file may be replacing other * older files. Implementations should remove those older files (if any) as * part of the commit of the new file. * <p> * This method is a trivial wrapper around * {@link #commitPackImpl(Collection, Collection)} that calls the * implementation and fires events. * * @param desc * description of the new packs. * @param replaces * if not null, list of packs to remove. * @throws java.io.IOException * the packs cannot be committed. On failure a rollback must * also be attempted by the caller. */ protected void commitPack(Collection<DfsPackDescription> desc, Collection<DfsPackDescription> replaces) throws IOException { commitPackImpl(desc, replaces); getRepository().fireEvent(new DfsPacksChangedEvent()); }
PackList scanPacks(PackList original) throws IOException { PackList o, n; synchronized (packList) { do { o = packList.get(); if (o != original) { // Another thread did the scan for us, while we // were blocked on the monitor above. // return o; } n = scanPacksImpl(o); if (n == o) return n; } while (!packList.compareAndSet(o, n)); } getRepository().fireEvent(new DfsPacksChangedEvent()); return n; }
private <T extends ObjectId> Iterable<FoundObject<T>> findAll( Iterable<T> objectIds) throws IOException { Collection<T> pending = new LinkedList<>(); for (T id : objectIds) { pending.add(id); } PackList packList = db.getPackList(); List<FoundObject<T>> r = new ArrayList<>(); findAllImpl(packList, pending, r); if (!pending.isEmpty() && packList.dirty()) { stats.scanPacks++; findAllImpl(db.scanPacks(packList), pending, r); } for (T t : pending) { r.add(new FoundObject<>(t)); } Collections.sort(r, FOUND_OBJECT_SORT); return r; }
ctx = objdb.newReader(); try { refdb.refresh(); objdb.clearCache(); packRefTreeGraph(pm); packGarbage(pm); objdb.commitPack(newPackDesc, toPrune()); rollback = false; return true; } finally { if (rollback) objdb.rollbackPack(newPackDesc);
try (DfsReader ctx = (DfsReader) objdb.newReader()) { PackConfig pc = new PackConfig(repo); pc.setIndexVersion(2); List<DfsPackDescription> remove = toPrune(); if (remove.size() > 0) objdb.commitPack( Collections.<DfsPackDescription>emptyList(), remove); DfsPackDescription pack = objdb.newPack(COMPACT); try { writePack(objdb, pack, pw, pm); objdb.commitPack(Collections.singletonList(pack), toPrune()); newPacks.add(pack); newStats.add(stats); } finally { if (rollback) objdb.rollbackPack(Collections.singletonList(pack));
objdb.commitPack(Collections.singletonList(packDsc), null); rollback = false; p.setPackIndex(packIndex); objdb.addPack(p); objdb.rollbackPack(Collections.singletonList(packDsc)); } finally { packDsc = null;
private void applyUpdates(RevWalk rw, List<ReceiveCommand> pending) throws IOException { List<Ref> newRefs = toNewRefs(rw, pending); long updateIndex = nextUpdateIndex(); Set<DfsPackDescription> prune = Collections.emptySet(); DfsPackDescription pack = odb.newPack(PackSource.INSERT); try (DfsOutputStream out = odb.writeFile(pack, REFTABLE)) { ReftableConfig cfg = DfsPackCompactor .configureReftable(reftableConfig, out); ReftableWriter.Stats stats; if (refdb.compactDuringCommit() && newRefs.size() * AVG_BYTES <= cfg.getRefBlockSize() && canCompactTopOfStack(cfg)) { ByteArrayOutputStream tmp = new ByteArrayOutputStream(); write(tmp, cfg, updateIndex, newRefs, pending); stats = compactTopOfStack(out, cfg, tmp.toByteArray()); prune = toPruneTopOfStack(); } else { stats = write(out, cfg, updateIndex, newRefs, pending); } pack.addFileExt(REFTABLE); pack.setReftableStats(stats); } odb.commitPack(Collections.singleton(pack), prune); odb.addReftable(pack, prune); refdb.clearCache(); }
private void checkPacks(ProgressMonitor pm, FsckError errors) throws IOException, FileNotFoundException { try (DfsReader ctx = objdb.newReader()) { for (DfsPackFile pack : objdb.getPacks()) { DfsPackDescription packDesc = pack.getPackDescription(); if (packDesc.getPackSource() == PackSource.UNREACHABLE_GARBAGE) { continue; } try (ReadableChannel rc = objdb.openFile(packDesc, PACK)) { verifyPack(pm, errors, ctx, pack, rc); } catch (MissingObjectException e) { errors.getMissingObjects().add(e.getObjectId()); } catch (CorruptPackIndexException e) { errors.getCorruptIndices().add(new CorruptIndex( pack.getPackDescription().getFileName(INDEX), e.getErrorType())); } } } checkGitModules(pm, errors); }
private List<DfsPackFile> sortPacksForSelectRepresentation() throws IOException { DfsPackFile[] packs = db.getPacks(); List<DfsPackFile> sorted = new ArrayList<>(packs.length); for (DfsPackFile p : packs) { if (p.getPackDescription().getPackSource() != UNREACHABLE_GARBAGE) { sorted.add(p); } } Collections.sort(sorted, PACK_SORT_FOR_REUSE); return sorted; }
DfsReaderOptions getOptions() { return db.getReaderOptions(); }
/** * Scan and list all available pack files in the repository. * * @return list of available packs. The returned array is shared with the * implementation and must not be modified by the caller. * @throws java.io.IOException * the pack list cannot be initialized. */ public DfsPackFile[] getPacks() throws IOException { return getPackList().packs; }
/** * Compact the pack files together. * * @param pm * progress monitor to receive updates on as packing may take a * while, depending on the size of the repository. * @throws java.io.IOException * the packs cannot be compacted. */ public void compact(ProgressMonitor pm) throws IOException { if (pm == null) { pm = NullProgressMonitor.INSTANCE; } DfsObjDatabase objdb = repo.getObjectDatabase(); try (DfsReader ctx = objdb.newReader()) { if (reftableConfig != null && !srcReftables.isEmpty()) { compactReftables(ctx); } compactPacks(ctx, pm); List<DfsPackDescription> commit = getNewPacks(); Collection<DfsPackDescription> remove = toPrune(); if (!commit.isEmpty() || !remove.isEmpty()) { objdb.commitPack(commit, remove); } } finally { rw = null; } }
/** * List currently known reftable files in the repository, without scanning. * * @return list of available reftables. The returned array is shared with * the implementation and must not be modified by the caller. */ public DfsReftable[] getCurrentReftables() { return getCurrentPackList().reftables; }
/** * Automatically select pack and reftables to be included, and add them. * <p> * Packs are selected based on size, smaller packs get included while bigger * ones are omitted. * * @return {@code this} * @throws java.io.IOException * existing packs cannot be read. */ public DfsPackCompactor autoAdd() throws IOException { DfsObjDatabase objdb = repo.getObjectDatabase(); for (DfsPackFile pack : objdb.getPacks()) { DfsPackDescription d = pack.getPackDescription(); if (d.getFileSize(PACK) < autoAddSize) add(pack); else exclude(pack); } if (reftableConfig != null) { for (DfsReftable table : objdb.getReftables()) { DfsPackDescription d = table.getPackDescription(); if (d.getPackSource() != GC && d.getFileSize(REFTABLE) < autoAddSize) { add(table); } } } return this; }
/** {@inheritDoc} */ @Override public ObjectId insert(int type, byte[] data, int off, int len) throws IOException { ObjectId id = idFor(type, data, off, len); if (objectMap != null && objectMap.contains(id)) return id; // Ignore unreachable (garbage) objects here. if (checkExisting && db.has(id, true)) return id; long offset = beginObject(type, len); packOut.compress.write(data, off, len); packOut.compress.finish(); return endObject(id, offset); }
/** {@inheritDoc} */ @Override public Collection<ObjectId> resolve(AbbreviatedObjectId id) throws IOException { if (id.isComplete()) return Collections.singleton(id.toObjectId()); HashSet<ObjectId> matches = new HashSet<>(4); PackList packList = db.getPackList(); resolveImpl(packList, id, matches); if (matches.size() < MAX_RESOLVE_MATCHES && packList.dirty()) { stats.scanPacks++; resolveImpl(db.scanPacks(packList), id, matches); } return matches; }
ctx = (DfsReader) objdb.newReader(); try { refdb.refresh(); objdb.clearCache(); objdb.commitPack(noPacks(), toPrune()); packRefTreeGraph(pm); packGarbage(pm); objdb.commitPack(newPackDesc, toPrune()); rollback = false; return true; } finally { if (rollback) objdb.rollbackPack(newPackDesc);
objdb.commitPack(Collections.singletonList(packDsc), null); rollback = false; p.setPackIndex(packIndex); objdb.addPack(p); objdb.rollbackPack(Collections.singletonList(packDsc)); } finally { packDsc = null;