|
|
|
@ -46,6 +46,11 @@ package org.eclipse.jgit.internal.storage.pack;
|
|
|
|
|
|
|
|
|
|
import static org.eclipse.jgit.internal.storage.pack.StoredObjectRepresentation.PACK_DELTA; |
|
|
|
|
import static org.eclipse.jgit.internal.storage.pack.StoredObjectRepresentation.PACK_WHOLE; |
|
|
|
|
import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; |
|
|
|
|
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; |
|
|
|
|
import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT; |
|
|
|
|
import static org.eclipse.jgit.lib.Constants.OBJ_TAG; |
|
|
|
|
import static org.eclipse.jgit.lib.Constants.OBJ_TREE; |
|
|
|
|
|
|
|
|
|
import java.io.IOException; |
|
|
|
|
import java.io.OutputStream; |
|
|
|
@ -203,12 +208,12 @@ public class PackWriter {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
private final BlockList<ObjectToPack> objectsLists[] = new BlockList[Constants.OBJ_TAG + 1]; |
|
|
|
|
private final BlockList<ObjectToPack> objectsLists[] = new BlockList[OBJ_TAG + 1]; |
|
|
|
|
{ |
|
|
|
|
objectsLists[Constants.OBJ_COMMIT] = new BlockList<ObjectToPack>(); |
|
|
|
|
objectsLists[Constants.OBJ_TREE] = new BlockList<ObjectToPack>(); |
|
|
|
|
objectsLists[Constants.OBJ_BLOB] = new BlockList<ObjectToPack>(); |
|
|
|
|
objectsLists[Constants.OBJ_TAG] = new BlockList<ObjectToPack>(); |
|
|
|
|
objectsLists[OBJ_COMMIT] = new BlockList<ObjectToPack>(); |
|
|
|
|
objectsLists[OBJ_TREE] = new BlockList<ObjectToPack>(); |
|
|
|
|
objectsLists[OBJ_BLOB] = new BlockList<ObjectToPack>(); |
|
|
|
|
objectsLists[OBJ_TAG] = new BlockList<ObjectToPack>(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private final ObjectIdOwnerMap<ObjectToPack> objectsMap = new ObjectIdOwnerMap<ObjectToPack>(); |
|
|
|
@ -531,10 +536,10 @@ public class PackWriter {
|
|
|
|
|
if (stats.totalObjects == 0) { |
|
|
|
|
long objCnt = 0; |
|
|
|
|
|
|
|
|
|
objCnt += objectsLists[Constants.OBJ_COMMIT].size(); |
|
|
|
|
objCnt += objectsLists[Constants.OBJ_TREE].size(); |
|
|
|
|
objCnt += objectsLists[Constants.OBJ_BLOB].size(); |
|
|
|
|
objCnt += objectsLists[Constants.OBJ_TAG].size(); |
|
|
|
|
objCnt += objectsLists[OBJ_COMMIT].size(); |
|
|
|
|
objCnt += objectsLists[OBJ_TREE].size(); |
|
|
|
|
objCnt += objectsLists[OBJ_BLOB].size(); |
|
|
|
|
objCnt += objectsLists[OBJ_TAG].size(); |
|
|
|
|
|
|
|
|
|
for (CachedPack pack : cachedPacks) |
|
|
|
|
objCnt += pack.getObjectCount(); |
|
|
|
@ -807,11 +812,11 @@ public class PackWriter {
|
|
|
|
|
* @return ObjectId representing SHA-1 name of a pack that was created. |
|
|
|
|
*/ |
|
|
|
|
public ObjectId computeName() { |
|
|
|
|
final byte[] buf = new byte[Constants.OBJECT_ID_LENGTH]; |
|
|
|
|
final byte[] buf = new byte[OBJECT_ID_LENGTH]; |
|
|
|
|
final MessageDigest md = Constants.newMessageDigest(); |
|
|
|
|
for (ObjectToPack otp : sortByName()) { |
|
|
|
|
otp.copyRawTo(buf, 0); |
|
|
|
|
md.update(buf, 0, Constants.OBJECT_ID_LENGTH); |
|
|
|
|
md.update(buf, 0, OBJECT_ID_LENGTH); |
|
|
|
|
} |
|
|
|
|
return ObjectId.fromRaw(md.digest()); |
|
|
|
|
} |
|
|
|
@ -888,16 +893,16 @@ public class PackWriter {
|
|
|
|
|
private List<ObjectToPack> sortByName() { |
|
|
|
|
if (sortedByName == null) { |
|
|
|
|
int cnt = 0; |
|
|
|
|
cnt += objectsLists[Constants.OBJ_COMMIT].size(); |
|
|
|
|
cnt += objectsLists[Constants.OBJ_TREE].size(); |
|
|
|
|
cnt += objectsLists[Constants.OBJ_BLOB].size(); |
|
|
|
|
cnt += objectsLists[Constants.OBJ_TAG].size(); |
|
|
|
|
cnt += objectsLists[OBJ_COMMIT].size(); |
|
|
|
|
cnt += objectsLists[OBJ_TREE].size(); |
|
|
|
|
cnt += objectsLists[OBJ_BLOB].size(); |
|
|
|
|
cnt += objectsLists[OBJ_TAG].size(); |
|
|
|
|
|
|
|
|
|
sortedByName = new BlockList<ObjectToPack>(cnt); |
|
|
|
|
sortedByName.addAll(objectsLists[Constants.OBJ_COMMIT]); |
|
|
|
|
sortedByName.addAll(objectsLists[Constants.OBJ_TREE]); |
|
|
|
|
sortedByName.addAll(objectsLists[Constants.OBJ_BLOB]); |
|
|
|
|
sortedByName.addAll(objectsLists[Constants.OBJ_TAG]); |
|
|
|
|
sortedByName.addAll(objectsLists[OBJ_COMMIT]); |
|
|
|
|
sortedByName.addAll(objectsLists[OBJ_TREE]); |
|
|
|
|
sortedByName.addAll(objectsLists[OBJ_BLOB]); |
|
|
|
|
sortedByName.addAll(objectsLists[OBJ_TAG]); |
|
|
|
|
Collections.sort(sortedByName); |
|
|
|
|
} |
|
|
|
|
return sortedByName; |
|
|
|
@ -1065,37 +1070,34 @@ public class PackWriter {
|
|
|
|
|
|
|
|
|
|
private void searchForReuse(ProgressMonitor monitor) throws IOException { |
|
|
|
|
long cnt = 0; |
|
|
|
|
cnt += objectsLists[Constants.OBJ_COMMIT].size(); |
|
|
|
|
cnt += objectsLists[Constants.OBJ_TREE].size(); |
|
|
|
|
cnt += objectsLists[Constants.OBJ_BLOB].size(); |
|
|
|
|
cnt += objectsLists[Constants.OBJ_TAG].size(); |
|
|
|
|
cnt += objectsLists[OBJ_COMMIT].size(); |
|
|
|
|
cnt += objectsLists[OBJ_TREE].size(); |
|
|
|
|
cnt += objectsLists[OBJ_BLOB].size(); |
|
|
|
|
cnt += objectsLists[OBJ_TAG].size(); |
|
|
|
|
|
|
|
|
|
long start = System.currentTimeMillis(); |
|
|
|
|
beginPhase(PackingPhase.FINDING_SOURCES, monitor, cnt); |
|
|
|
|
|
|
|
|
|
if (cnt <= 4096) { |
|
|
|
|
// For small object counts, do everything as one list.
|
|
|
|
|
BlockList<ObjectToPack> tmp = new BlockList<ObjectToPack>((int) cnt); |
|
|
|
|
tmp.addAll(objectsLists[Constants.OBJ_TAG]); |
|
|
|
|
tmp.addAll(objectsLists[Constants.OBJ_COMMIT]); |
|
|
|
|
tmp.addAll(objectsLists[Constants.OBJ_TREE]); |
|
|
|
|
tmp.addAll(objectsLists[Constants.OBJ_BLOB]); |
|
|
|
|
tmp.addAll(objectsLists[OBJ_TAG]); |
|
|
|
|
tmp.addAll(objectsLists[OBJ_COMMIT]); |
|
|
|
|
tmp.addAll(objectsLists[OBJ_TREE]); |
|
|
|
|
tmp.addAll(objectsLists[OBJ_BLOB]); |
|
|
|
|
searchForReuse(monitor, tmp); |
|
|
|
|
if (pruneCurrentObjectList) { |
|
|
|
|
// If the list was pruned, we need to re-prune the main lists.
|
|
|
|
|
pruneEdgesFromObjectList(objectsLists[Constants.OBJ_COMMIT]); |
|
|
|
|
pruneEdgesFromObjectList(objectsLists[Constants.OBJ_TREE]); |
|
|
|
|
pruneEdgesFromObjectList(objectsLists[Constants.OBJ_BLOB]); |
|
|
|
|
pruneEdgesFromObjectList(objectsLists[Constants.OBJ_TAG]); |
|
|
|
|
pruneEdgesFromObjectList(objectsLists[OBJ_COMMIT]); |
|
|
|
|
pruneEdgesFromObjectList(objectsLists[OBJ_TREE]); |
|
|
|
|
pruneEdgesFromObjectList(objectsLists[OBJ_BLOB]); |
|
|
|
|
pruneEdgesFromObjectList(objectsLists[OBJ_TAG]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
searchForReuse(monitor, objectsLists[Constants.OBJ_TAG]); |
|
|
|
|
searchForReuse(monitor, objectsLists[Constants.OBJ_COMMIT]); |
|
|
|
|
searchForReuse(monitor, objectsLists[Constants.OBJ_TREE]); |
|
|
|
|
searchForReuse(monitor, objectsLists[Constants.OBJ_BLOB]); |
|
|
|
|
searchForReuse(monitor, objectsLists[OBJ_TAG]); |
|
|
|
|
searchForReuse(monitor, objectsLists[OBJ_COMMIT]); |
|
|
|
|
searchForReuse(monitor, objectsLists[OBJ_TREE]); |
|
|
|
|
searchForReuse(monitor, objectsLists[OBJ_BLOB]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
endPhase(monitor); |
|
|
|
|
stats.timeSearchingForReuse = System.currentTimeMillis() - start; |
|
|
|
|
} |
|
|
|
@ -1116,12 +1118,12 @@ public class PackWriter {
|
|
|
|
|
// bother examining those types here.
|
|
|
|
|
//
|
|
|
|
|
ObjectToPack[] list = new ObjectToPack[ |
|
|
|
|
objectsLists[Constants.OBJ_TREE].size() |
|
|
|
|
+ objectsLists[Constants.OBJ_BLOB].size() |
|
|
|
|
objectsLists[OBJ_TREE].size() |
|
|
|
|
+ objectsLists[OBJ_BLOB].size() |
|
|
|
|
+ edgeObjects.size()]; |
|
|
|
|
int cnt = 0; |
|
|
|
|
cnt = findObjectsNeedingDelta(list, cnt, Constants.OBJ_TREE); |
|
|
|
|
cnt = findObjectsNeedingDelta(list, cnt, Constants.OBJ_BLOB); |
|
|
|
|
cnt = findObjectsNeedingDelta(list, cnt, OBJ_TREE); |
|
|
|
|
cnt = findObjectsNeedingDelta(list, cnt, OBJ_BLOB); |
|
|
|
|
if (cnt == 0) |
|
|
|
|
return; |
|
|
|
|
int nonEdgeCnt = cnt; |
|
|
|
@ -1408,10 +1410,10 @@ public class PackWriter {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void writeObjects(PackOutputStream out) throws IOException { |
|
|
|
|
writeObjects(out, objectsLists[Constants.OBJ_COMMIT]); |
|
|
|
|
writeObjects(out, objectsLists[Constants.OBJ_TAG]); |
|
|
|
|
writeObjects(out, objectsLists[Constants.OBJ_TREE]); |
|
|
|
|
writeObjects(out, objectsLists[Constants.OBJ_BLOB]); |
|
|
|
|
writeObjects(out, objectsLists[OBJ_COMMIT]); |
|
|
|
|
writeObjects(out, objectsLists[OBJ_TAG]); |
|
|
|
|
writeObjects(out, objectsLists[OBJ_TREE]); |
|
|
|
|
writeObjects(out, objectsLists[OBJ_BLOB]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void writeObjects(PackOutputStream out, List<ObjectToPack> list) |
|
|
|
@ -1986,7 +1988,7 @@ public class PackWriter {
|
|
|
|
|
PackWriterBitmapPreparer bitmapPreparer = new PackWriterBitmapPreparer( |
|
|
|
|
reader, writeBitmaps, pm, stats.interestingObjects); |
|
|
|
|
|
|
|
|
|
int numCommits = objectsLists[Constants.OBJ_COMMIT].size(); |
|
|
|
|
int numCommits = objectsLists[OBJ_COMMIT].size(); |
|
|
|
|
Collection<PackWriterBitmapPreparer.BitmapCommit> selectedCommits = |
|
|
|
|
bitmapPreparer.doCommitSelection(numCommits); |
|
|
|
|
|
|
|
|
@ -2140,10 +2142,10 @@ public class PackWriter {
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
objectTypes = new ObjectType[5]; |
|
|
|
|
objectTypes[Constants.OBJ_COMMIT] = new ObjectType(); |
|
|
|
|
objectTypes[Constants.OBJ_TREE] = new ObjectType(); |
|
|
|
|
objectTypes[Constants.OBJ_BLOB] = new ObjectType(); |
|
|
|
|
objectTypes[Constants.OBJ_TAG] = new ObjectType(); |
|
|
|
|
objectTypes[OBJ_COMMIT] = new ObjectType(); |
|
|
|
|
objectTypes[OBJ_TREE] = new ObjectType(); |
|
|
|
|
objectTypes[OBJ_BLOB] = new ObjectType(); |
|
|
|
|
objectTypes[OBJ_TAG] = new ObjectType(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -2364,10 +2366,10 @@ public class PackWriter {
|
|
|
|
|
|
|
|
|
|
State snapshot() { |
|
|
|
|
long objCnt = 0; |
|
|
|
|
objCnt += objectsLists[Constants.OBJ_COMMIT].size(); |
|
|
|
|
objCnt += objectsLists[Constants.OBJ_TREE].size(); |
|
|
|
|
objCnt += objectsLists[Constants.OBJ_BLOB].size(); |
|
|
|
|
objCnt += objectsLists[Constants.OBJ_TAG].size(); |
|
|
|
|
objCnt += objectsLists[OBJ_COMMIT].size(); |
|
|
|
|
objCnt += objectsLists[OBJ_TREE].size(); |
|
|
|
|
objCnt += objectsLists[OBJ_BLOB].size(); |
|
|
|
|
objCnt += objectsLists[OBJ_TAG].size(); |
|
|
|
|
// Exclude CachedPacks.
|
|
|
|
|
|
|
|
|
|
long bytesUsed = OBJECT_TO_PACK_SIZE * objCnt; |
|
|
|
|