@@ -3,6 +3,7 @@ package idxfile
3
3
import (
4
4
"bytes"
5
5
"io"
6
+ "sort"
6
7
7
8
"gopkg.in/src-d/go-git.v4/plumbing"
8
9
"gopkg.in/src-d/go-git.v4/utils/binary"
@@ -34,6 +35,9 @@ type Index interface {
34
35
Count () (int64 , error )
35
36
// Entries returns an iterator to retrieve all index entries.
36
37
Entries () (EntryIter , error )
38
+ // EntriesByOffset returns an iterator to retrieve all index entries ordered
39
+ // by offset.
40
+ EntriesByOffset () (EntryIter , error )
37
41
}
38
42
39
43
// MemoryIndex is the in memory representation of an idx file.
@@ -215,6 +219,36 @@ func (idx *MemoryIndex) Entries() (EntryIter, error) {
215
219
return & idxfileEntryIter {idx , 0 , 0 , 0 }, nil
216
220
}
217
221
222
+ // EntriesByOffset implements the Index interface.
223
+ func (idx * MemoryIndex ) EntriesByOffset () (EntryIter , error ) {
224
+ count , err := idx .Count ()
225
+ if err != nil {
226
+ return nil , err
227
+ }
228
+
229
+ iter := & idxfileEntryOffsetIter {
230
+ entries : make (entriesByOffset , count ),
231
+ }
232
+
233
+ entries , err := idx .Entries ()
234
+ if err != nil {
235
+ return nil , err
236
+ }
237
+
238
+ for pos := 0 ; int64 (pos ) < count ; pos ++ {
239
+ entry , err := entries .Next ()
240
+ if err != nil {
241
+ return nil , err
242
+ }
243
+
244
+ iter .entries [pos ] = entry
245
+ }
246
+
247
+ sort .Sort (iter .entries )
248
+
249
+ return iter , nil
250
+ }
251
+
218
252
// EntryIter is an iterator that will return the entries in a packfile index.
219
253
type EntryIter interface {
220
254
// Next returns the next entry in the packfile index.
@@ -276,3 +310,38 @@ type Entry struct {
276
310
CRC32 uint32
277
311
Offset uint64
278
312
}
313
+
314
+ type idxfileEntryOffsetIter struct {
315
+ entries entriesByOffset
316
+ pos int
317
+ }
318
+
319
+ func (i * idxfileEntryOffsetIter ) Next () (* Entry , error ) {
320
+ if i .pos >= len (i .entries ) {
321
+ return nil , io .EOF
322
+ }
323
+
324
+ entry := i .entries [i .pos ]
325
+ i .pos ++
326
+
327
+ return entry , nil
328
+ }
329
+
330
+ func (i * idxfileEntryOffsetIter ) Close () error {
331
+ i .pos = len (i .entries ) + 1
332
+ return nil
333
+ }
334
+
335
+ type entriesByOffset []* Entry
336
+
337
+ func (o entriesByOffset ) Len () int {
338
+ return len (o )
339
+ }
340
+
341
+ func (o entriesByOffset ) Less (i int , j int ) bool {
342
+ return o [i ].Offset < o [j ].Offset
343
+ }
344
+
345
+ func (o entriesByOffset ) Swap (i int , j int ) {
346
+ o [i ], o [j ] = o [j ], o [i ]
347
+ }
0 commit comments