private void sendPackedObjects( final List<ObjectId> toSend, final Set<ObjectId> roots, Deduplicator deduplicator, final ProgressListener progress) { Set<ObjectId> sent = new HashSet<ObjectId>(); while (!toSend.isEmpty()) { try { BinaryPackedObjects.Callback callback = new BinaryPackedObjects.Callback() { @Override public void callback(Supplier<RevObject> supplier) { RevObject object = supplier.get(); progress.setProgress(progress.getProgress() + 1); if (object instanceof RevCommit) { RevCommit commit = (RevCommit) object; toSend.remove(commit.getId()); roots.removeAll(commit.getParentIds()); roots.add(commit.getId()); } } }; ObjectDatabase database = localRepository.objectDatabase(); BinaryPackedObjects packer = new BinaryPackedObjects(database); ImmutableList<ObjectId> have = ImmutableList.copyOf(roots); final boolean traverseCommits = false; Stopwatch sw = Stopwatch.createStarted(); ObjectSerializingFactory serializer = DataStreamSerializationFactoryV1.INSTANCE; SendObjectsConnectionFactory outFactory; ObjectFunnel objectFunnel; outFactory = new SendObjectsConnectionFactory(repositoryURL); int pushBytesLimit = parsePushLimit(); objectFunnel = ObjectFunnels.newFunnel(outFactory, serializer, pushBytesLimit); final long writtenObjectsCount = packer.write(objectFunnel, toSend, have, sent, callback, traverseCommits, deduplicator); objectFunnel.close(); sw.stop(); long compressedSize = outFactory.compressedSize; long uncompressedSize = outFactory.uncompressedSize; LOGGER.info( String.format( "HttpRemoteRepo: Written %,d objects." + " Time to process: %s." + " Compressed size: %,d bytes. Uncompressed size: %,d bytes.", writtenObjectsCount, sw, compressedSize, uncompressedSize)); } catch (IOException e) { Throwables.propagate(e); } } }
/** * Retrieve objects from the remote repository, and update have/want lists accordingly. * Specifically, any retrieved commits are removed from the want list and added to the have list, * and any parents of those commits are removed from the have list (it only represents the most * recent common commits.) Retrieved objects are added to the local repository, and the want/have * lists are updated in-place. * * @param want a list of ObjectIds that need to be fetched * @param have a list of ObjectIds that are in common with the remote repository * @param progress */ private void fetchMoreData( final List<ObjectId> want, final Set<ObjectId> have, final ProgressListener progress) { final JsonObject message = createFetchMessage(want, have); final URL resourceURL; try { resourceURL = new URL(repositoryURL.toString() + "/repo/batchobjects"); } catch (MalformedURLException e) { throw Throwables.propagate(e); } final HttpURLConnection connection; try { final Gson gson = new Gson(); OutputStream out; final Writer writer; connection = (HttpURLConnection) resourceURL.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.addRequestProperty("Accept-Encoding", "gzip"); out = connection.getOutputStream(); writer = new OutputStreamWriter(out); gson.toJson(message, writer); writer.flush(); out.flush(); } catch (IOException e) { throw Throwables.propagate(e); } final HttpUtils.ReportingInputStream in = HttpUtils.getResponseStream(connection); BinaryPackedObjects unpacker = new BinaryPackedObjects(localRepository.objectDatabase()); BinaryPackedObjects.Callback callback = new BinaryPackedObjects.Callback() { @Override public void callback(Supplier<RevObject> supplier) { RevObject object = supplier.get(); progress.setProgress(progress.getProgress() + 1); if (object instanceof RevCommit) { RevCommit commit = (RevCommit) object; want.remove(commit.getId()); have.removeAll(commit.getParentIds()); have.add(commit.getId()); } else if (object instanceof RevTag) { RevTag tag = (RevTag) object; want.remove(tag.getId()); have.remove(tag.getCommitId()); have.add(tag.getId()); } } }; Stopwatch sw = Stopwatch.createStarted(); IngestResults ingestResults = unpacker.ingest(in, callback); sw.stop(); String msg = String.format( "Processed %,d objects. Inserted: %,d. Existing: %,d. Time: %s. Compressed size: %,d bytes. Uncompressed size: %,d bytes.", ingestResults.total(), ingestResults.getInserted(), ingestResults.getExisting(), sw, in.compressedSize(), in.unCompressedSize()); LOGGER.info(msg); progress.setDescription(msg); }