5
5
package git
6
6
7
7
import (
8
+ "fmt"
9
+ "path"
10
+ "path/filepath"
8
11
"sort"
9
12
"strconv"
10
13
"strings"
@@ -84,10 +87,10 @@ var sorter = []func(t1, t2 *TreeEntry) bool{
84
87
},
85
88
}
86
89
87
- func (bs Entries ) Len () int { return len (bs ) }
88
- func (bs Entries ) Swap (i , j int ) { bs [i ], bs [j ] = bs [j ], bs [i ] }
89
- func (bs Entries ) Less (i , j int ) bool {
90
- t1 , t2 := bs [i ], bs [j ]
90
+ func (tes Entries ) Len () int { return len (tes ) }
91
+ func (tes Entries ) Swap (i , j int ) { tes [i ], tes [j ] = tes [j ], tes [i ] }
92
+ func (tes Entries ) Less (i , j int ) bool {
93
+ t1 , t2 := tes [i ], tes [j ]
91
94
var k int
92
95
for k = 0 ; k < len (sorter )- 1 ; k ++ {
93
96
sort := sorter [k ]
@@ -101,6 +104,83 @@ func (bs Entries) Less(i, j int) bool {
101
104
return sorter [k ](t1 , t2 )
102
105
}
103
106
104
- func (bs Entries ) Sort () {
105
- sort .Sort (bs )
107
+ func (tes Entries ) Sort () {
108
+ sort .Sort (tes )
109
+ }
110
+
111
+ type commitInfo struct {
112
+ id string
113
+ infos []interface {}
114
+ err error
115
+ }
116
+
117
+ // GetCommitsInfo takes advantages of concurrey to speed up getting information
118
+ // of all commits that are corresponding to these entries.
119
+ // TODO: limit max goroutines at same time
120
+ func (tes Entries ) GetCommitsInfo (commit * Commit , treePath string ) ([][]interface {}, error ) {
121
+ if len (tes ) == 0 {
122
+ return nil , nil
123
+ }
124
+
125
+ revChan := make (chan commitInfo , 10 )
126
+
127
+ infoMap := make (map [string ][]interface {}, len (tes ))
128
+ for i := range tes {
129
+ if tes [i ].Type != OBJECT_COMMIT {
130
+ go func (i int ) {
131
+ cinfo := commitInfo {id : tes [i ].ID .String ()}
132
+ c , err := commit .GetCommitByPath (filepath .Join (treePath , tes [i ].Name ()))
133
+ if err != nil {
134
+ cinfo .err = fmt .Errorf ("GetCommitByPath (%s/%s): %v" , treePath , tes [i ].Name (), err )
135
+ } else {
136
+ cinfo .infos = []interface {}{tes [i ], c }
137
+ }
138
+ revChan <- cinfo
139
+ }(i )
140
+ continue
141
+ }
142
+
143
+ // Handle submodule
144
+ go func (i int ) {
145
+ cinfo := commitInfo {id : tes [i ].ID .String ()}
146
+ sm , err := commit .GetSubModule (path .Join (treePath , tes [i ].Name ()))
147
+ if err != nil {
148
+ cinfo .err = fmt .Errorf ("GetSubModule (%s/%s): %v" , treePath , tes [i ].Name (), err )
149
+ revChan <- cinfo
150
+ return
151
+ }
152
+
153
+ smUrl := ""
154
+ if sm != nil {
155
+ smUrl = sm .Url
156
+ }
157
+
158
+ c , err := commit .GetCommitByPath (filepath .Join (treePath , tes [i ].Name ()))
159
+ if err != nil {
160
+ cinfo .err = fmt .Errorf ("GetCommitByPath (%s/%s): %v" , treePath , tes [i ].Name (), err )
161
+ } else {
162
+ cinfo .infos = []interface {}{tes [i ], NewSubModuleFile (c , smUrl , tes [i ].ID .String ())}
163
+ }
164
+ revChan <- cinfo
165
+ }(i )
166
+ }
167
+
168
+ i := 0
169
+ for info := range revChan {
170
+ if info .err != nil {
171
+ return nil , info .err
172
+ }
173
+
174
+ infoMap [info .id ] = info .infos
175
+ i ++
176
+ if i == len (tes ) {
177
+ break
178
+ }
179
+ }
180
+
181
+ commitsInfo := make ([][]interface {}, len (tes ))
182
+ for i := 0 ; i < len (tes ); i ++ {
183
+ commitsInfo [i ] = infoMap [tes [i ].ID .String ()]
184
+ }
185
+ return commitsInfo , nil
106
186
}
0 commit comments