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)
list.map { case (objectId, fileMode, path, name) =>
FileInfo(
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 (true , false) => true
case (false, true ) => false case (false, true ) => false
case _ => file1.name.compareTo(file2.name) < 0 case _ => file1.name.compareTo(file2.name) < 0
}} }
}.toList
} }
/** /**
@@ -270,16 +274,27 @@ 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] =
getLatestCommitFromPaths(git, List(path), revision).get(path)
/**
* Returns the list of latest RevCommit of the specified paths.
*
* @param git the Git object
* @param paths the list of paths
* @param revision the branch name or commit id
* @return the list of latest commit
*/
def getLatestCommitFromPaths(git: Git, paths: List[String], revision: String): Map[String, RevCommit] = {
val map = new scala.collection.mutable.HashMap[String, RevCommit]
val revWalk = new RevWalk(git.getRepository) val revWalk = new RevWalk(git.getRepository)
revWalk.markStart(revWalk.parseCommit(git.getRepository.resolve(revision))) revWalk.markStart(revWalk.parseCommit(git.getRepository.resolve(revision)))
revWalk.sort(RevSort.REVERSE); revWalk.sort(RevSort.REVERSE);
val i = revWalk.iterator val i = revWalk.iterator
// TODO DON'T use var! while(i.hasNext && map.size != paths.length){
var result: RevCommit = null
while(i.hasNext){
val commit = i.next val commit = i.next
if(commit.getParentCount == 0){ if(commit.getParentCount == 0){
// Initial commit // Initial commit
@@ -287,9 +302,11 @@ object JGitUtil {
treeWalk.reset() treeWalk.reset()
treeWalk.setRecursive(true) treeWalk.setRecursive(true)
treeWalk.addTree(commit.getTree) treeWalk.addTree(commit.getTree)
while (treeWalk.next && result == null) { while (treeWalk.next) {
if(treeWalk.getPathString.startsWith(path)){ paths.foreach { path =>
result = commit if(treeWalk.getPathString.startsWith(path) && !map.contains(path)){
map.put(path, commit)
}
} }
} }
treeWalk.release treeWalk.release
@@ -300,17 +317,18 @@ object JGitUtil {
df.setDiffComparator(RawTextComparator.DEFAULT) df.setDiffComparator(RawTextComparator.DEFAULT)
df.setDetectRenames(true) df.setDetectRenames(true)
val diffs = df.scan(parent.getTree(), commit.getTree) val diffs = df.scan(parent.getTree(), commit.getTree)
val find = diffs.asScala.find { diff => diffs.asScala.foreach { diff =>
val objectId = diff.getNewId.name paths.foreach { path =>
(diff.getChangeType != ChangeType.DELETE && diff.getNewPath.startsWith(path)) if(diff.getChangeType != ChangeType.DELETE && diff.getNewPath.startsWith(path) && !map.contains(path)){
} map.put(path, commit)
if(find != None){
result = commit
} }
} }
}
}
revWalk.release revWalk.release
} }
result map.toMap
} }
/** /**