Improve performance of the file list.

This commit is contained in:
takezoe
2013-06-06 16:34:00 +09:00
parent 1b4db5e6c6
commit 497bc61107

View File

@@ -14,6 +14,7 @@ import org.eclipse.jgit.diff.DiffEntry.ChangeType
import org.eclipse.jgit.util.io.DisabledOutputStream import org.eclipse.jgit.util.io.DisabledOutputStream
import org.eclipse.jgit.errors.MissingObjectException import org.eclipse.jgit.errors.MissingObjectException
import java.util.Date import java.util.Date
import scala.collection.mutable
/** /**
* Provides complex JGit operations. * Provides complex JGit operations.
@@ -167,28 +168,31 @@ object JGitUtil {
}) })
} }
val list = new scala.collection.mutable.ListBuffer[FileInfo] val list = new scala.collection.mutable.ListBuffer[(ObjectId, FileMode, String, String)]
while (treeWalk.next()) { while (treeWalk.next()) {
val fileCommit = JGitUtil.getLatestCommitFromPath(git, treeWalk.getPathString, revision) list.append((treeWalk.getObjectId(0), treeWalk.getFileMode(0), treeWalk.getPathString, treeWalk.getNameString))
list.append(FileInfo(
treeWalk.getObjectId(0),
treeWalk.getFileMode(0) == FileMode.TREE,
treeWalk.getNameString,
fileCommit.getCommitterIdent.getWhen,
fileCommit.getShortMessage,
fileCommit.getCommitterIdent.getName)
)
} }
treeWalk.release treeWalk.release
revWalk.dispose revWalk.dispose
list.toList.sortWith { (file1, file2) => (file1.isDirectory, file2.isDirectory) match { val commits = getLatestCommitFromPaths(git, list.toList.map(_._3), revision)
case (true , false) => true list.map { case (objectId, fileMode, path, name) =>
case (false, true ) => false FileInfo(
case _ => file1.name.compareTo(file2.name) < 0 objectId,
}} fileMode == FileMode.TREE,
name,
commits(path).getCommitterIdent.getWhen,
commits(path).getShortMessage,
commits(path).getCommitterIdent.getName)
}.sortWith { (file1, file2) =>
(file1.isDirectory, file2.isDirectory) match {
case (true , false) => true
case (false, true ) => false
case _ => file1.name.compareTo(file2.name) < 0
}
}.toList
} }
/** /**
@@ -270,49 +274,63 @@ object JGitUtil {
* @param revision the branch name or commit id * @param revision the branch name or commit id
* @return the latest commit * @return the latest commit
*/ */
def getLatestCommitFromPath(git: Git, path: String, revision: String): RevCommit = { def getLatestCommitFromPath(git: Git, path: String, revision: String): Option[RevCommit] =
val revWalk = new RevWalk(git.getRepository) getLatestCommitFromPaths(git, List(path), revision).get(path)
revWalk.markStart(revWalk.parseCommit(git.getRepository.resolve(revision)))
revWalk.sort(RevSort.REVERSE); /**
val i = revWalk.iterator * Returns the list of latest RevCommit of the specified paths.
*
// TODO DON'T use var! * @param git the Git object
var result: RevCommit = null * @param paths the list of paths
* @param revision the branch name or commit id
while(i.hasNext){ * @return the list of latest commit
val commit = i.next */
if(commit.getParentCount == 0){ def getLatestCommitFromPaths(git: Git, paths: List[String], revision: String): Map[String, RevCommit] = {
// Initial commit
val treeWalk = new TreeWalk(git.getRepository) val map = new scala.collection.mutable.HashMap[String, RevCommit]
treeWalk.reset()
treeWalk.setRecursive(true) val revWalk = new RevWalk(git.getRepository)
treeWalk.addTree(commit.getTree) revWalk.markStart(revWalk.parseCommit(git.getRepository.resolve(revision)))
while (treeWalk.next && result == null) { revWalk.sort(RevSort.REVERSE);
if(treeWalk.getPathString.startsWith(path)){ val i = revWalk.iterator
result = commit
while(i.hasNext && map.size != paths.length){
val commit = i.next
if(commit.getParentCount == 0){
// Initial commit
val treeWalk = new TreeWalk(git.getRepository)
treeWalk.reset()
treeWalk.setRecursive(true)
treeWalk.addTree(commit.getTree)
while (treeWalk.next) {
paths.foreach { path =>
if(treeWalk.getPathString.startsWith(path) && !map.contains(path)){
map.put(path, commit)
} }
} }
treeWalk.release }
} else { treeWalk.release
val parent = revWalk.parseCommit(commit.getParent(0).getId()) } else {
val df = new DiffFormatter(DisabledOutputStream.INSTANCE) val parent = revWalk.parseCommit(commit.getParent(0).getId())
df.setRepository(git.getRepository) val df = new DiffFormatter(DisabledOutputStream.INSTANCE)
df.setDiffComparator(RawTextComparator.DEFAULT) df.setRepository(git.getRepository)
df.setDetectRenames(true) df.setDiffComparator(RawTextComparator.DEFAULT)
val diffs = df.scan(parent.getTree(), commit.getTree) df.setDetectRenames(true)
val find = diffs.asScala.find { diff => val diffs = df.scan(parent.getTree(), commit.getTree)
val objectId = diff.getNewId.name diffs.asScala.foreach { diff =>
(diff.getChangeType != ChangeType.DELETE && diff.getNewPath.startsWith(path)) paths.foreach { path =>
} if(diff.getChangeType != ChangeType.DELETE && diff.getNewPath.startsWith(path) && !map.contains(path)){
if(find != None){ map.put(path, commit)
result = commit }
} }
} }
revWalk.release
} }
result
revWalk.release
}
map.toMap
} }
/** /**
* Get object content of the given id as String from the Git repository. * Get object content of the given id as String from the Git repository.
* *