@@ -12,6 +12,7 @@ import app.model.LocalRepo
1212import app.model.Repo
1313import app.model.Fact
1414import app.utils.RepoHelper
15+ import io.reactivex.Observable
1516import org.eclipse.jgit.diff.DiffFormatter
1617import org.eclipse.jgit.diff.DiffEntry
1718import org.eclipse.jgit.diff.RawText
@@ -87,10 +88,14 @@ class CodeLongevity(private val localRepo: LocalRepo,
8788 val tail: RevCommit ? =
8889 if (tailRev != " " ) RevWalk (repo).parseCommit(repo.resolve(tailRev))
8990 else null
91+ val df = DiffFormatter (DisabledOutputStream .INSTANCE )
9092
91- fun update () {
92- val codeLines = compute()
93+ init {
94+ df.setRepository(repo)
95+ df.setDetectRenames(true )
96+ }
9397
98+ fun update () {
9499 // TODO(anatoly): Add emails from server or hashAll.
95100 val emails = hashSetOf(localRepo.author.email)
96101
@@ -99,20 +104,20 @@ class CodeLongevity(private val localRepo: LocalRepo,
99104 val totals: MutableMap <String , Int > = emails.associate { Pair (it, 0 ) }
100105 .toMutableMap()
101106
102- val repoTotal: Int = codeLines.size
107+ var repoTotal: Int = 0
103108 var repoSum: Long = 0
104- for (line in codeLines) {
109+ getLinesObservable().blockingSubscribe { line ->
110+ repoTotal++
105111 repoSum + = line.age
106112
107113 val email = line.from.commit.authorIdent.emailAddress
108- if (! emails.contains(email)) {
109- continue
110- }
111- Logger .debug(line.toString())
112- Logger .debug(" Age: ${line.age} secs" )
114+ if (emails.contains(email)) {
115+ Logger .debug(line.toString())
116+ Logger .debug(" Age: ${line.age} secs" )
113117
114- sums[email] = sums[email]!! + line.age
115- totals[email] = totals[email]!! + 1
118+ sums[email] = sums[email]!! + line.age
119+ totals[email] = totals[email]!! + 1
120+ }
116121 }
117122
118123 val secondsInDay = 86400
@@ -146,12 +151,23 @@ class CodeLongevity(private val localRepo: LocalRepo,
146151 }
147152
148153 /* *
149- * Scans through the repo for alive and deleted code lines and returns
150- * a list of all code lines, both alive and deleted, between the given
151- * revisions.
154+ * Returns a list of code lines, both alive and deleted, between
155+ * the revisions of the repo.
152156 */
153- fun compute () : List <CodeLine > {
157+ fun getLinesList () : List <CodeLine > {
154158 val codeLines: MutableList <CodeLine > = mutableListOf ()
159+ getLinesObservable().blockingSubscribe { line ->
160+ codeLines.add(line)
161+ }
162+ return codeLines
163+ }
164+
165+ /* *
166+ * Returns an observable for for code lines, both alive and deleted, between
167+ * the revisions of the repo.
168+ */
169+ private fun getLinesObservable (): Observable <CodeLine > =
170+ Observable .create { subscriber ->
155171
156172 val treeWalk = TreeWalk (repo)
157173 treeWalk.setRecursive(true )
@@ -173,30 +189,9 @@ class CodeLongevity(private val localRepo: LocalRepo,
173189 }
174190 }
175191
176- val df = DiffFormatter (DisabledOutputStream .INSTANCE )
177- df.setRepository(repo)
178- df.setDetectRenames(true )
179-
180- val revWalk = RevWalk (repo)
181- revWalk.markStart(head)
182-
183- var commit: RevCommit ? = revWalk.next() // move the walker to the head
184- while (commit != null && commit != tail) {
185- val parentCommit: RevCommit ? = revWalk.next()
186-
187- Logger .debug(" commit: ${commit.getName()} ; " +
188- " '${commit.getShortMessage()} '" )
189- if (parentCommit != null ) {
190- Logger .debug(" parent commit: ${parentCommit.getName()} ; "
191- + " '${parentCommit.getShortMessage()} '" )
192- }
193- else {
194- Logger .debug(" parent commit: null" )
195- }
196-
192+ getDiffsObservable().blockingSubscribe { (commit, diffs) ->
197193 // A step back in commits history. Update the files map according
198194 // to the diff.
199- val diffs = df.scan(parentCommit, commit)
200195 for (diff in diffs) {
201196 val oldPath = diff.getOldPath()
202197 val oldId = diff.getOldId().toObjectId()
@@ -250,7 +245,7 @@ class CodeLongevity(private val localRepo: LocalRepo,
250245 val from = RevCommitLine (commit, newPath, idx)
251246 var to = lines.get(idx)
252247 val cl = CodeLine (from, to, fileText.getString(idx))
253- codeLines.add (cl)
248+ subscriber.onNext (cl)
254249 Logger .debug(" Collected: ${cl.toString()} " )
255250 }
256251 lines.subList(insStart, insEnd).clear()
@@ -280,7 +275,6 @@ class CodeLongevity(private val localRepo: LocalRepo,
280275 files.set(oldPath, files.remove(newPath)!! )
281276 }
282277 }
283- commit = parentCommit
284278 }
285279
286280 // If a tail revision was given then the map has to contain unclaimed
@@ -293,11 +287,41 @@ class CodeLongevity(private val localRepo: LocalRepo,
293287 val from = RevCommitLine (tail, file, idx)
294288 val cl = CodeLine (from, lines[idx],
295289 " no data (too lazy to compute)" )
296- codeLines.add (cl)
290+ subscriber.onNext (cl)
297291 }
298292 }
299293 }
300294
301- return codeLines
295+ subscriber.onComplete()
296+ }
297+
298+ /* *
299+ * Iterates over the diffs between commits in the repo's history.
300+ */
301+ private fun getDiffsObservable (): Observable <Pair <RevCommit , List <DiffEntry >>> =
302+ Observable .create { subscriber ->
303+
304+ val revWalk = RevWalk (repo)
305+ revWalk.markStart(head)
306+
307+ var commit: RevCommit ? = revWalk.next() // move the walker to the head
308+ while (commit != null && commit != tail) {
309+ val parentCommit: RevCommit ? = revWalk.next()
310+
311+ Logger .debug(" commit: ${commit.getName()} ; " +
312+ " '${commit.getShortMessage()} '" )
313+ if (parentCommit != null ) {
314+ Logger .debug(" parent commit: ${parentCommit.getName()} ; "
315+ + " '${parentCommit.getShortMessage()} '" )
316+ }
317+ else {
318+ Logger .debug(" parent commit: null" )
319+ }
320+
321+ subscriber.onNext(Pair (commit, df.scan(parentCommit, commit)))
322+ commit = parentCommit
323+ }
324+
325+ subscriber.onComplete()
302326 }
303327}
0 commit comments