@@ -3,6 +3,7 @@ package idxfile
33import (
44 "bytes"
55 "io"
6+ "sort"
67
78 "gopkg.in/src-d/go-git.v4/plumbing"
89 "gopkg.in/src-d/go-git.v4/utils/binary"
@@ -34,6 +35,9 @@ type Index interface {
3435 Count () (int64 , error )
3536 // Entries returns an iterator to retrieve all index entries.
3637 Entries () (EntryIter , error )
38+ // EntriesByOffset returns an iterator to retrieve all index entries ordered
39+ // by offset.
40+ EntriesByOffset () (EntryIter , error )
3741}
3842
3943// MemoryIndex is the in memory representation of an idx file.
@@ -215,6 +219,36 @@ func (idx *MemoryIndex) Entries() (EntryIter, error) {
215219 return & idxfileEntryIter {idx , 0 , 0 , 0 }, nil
216220}
217221
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+
218252// EntryIter is an iterator that will return the entries in a packfile index.
219253type EntryIter interface {
220254 // Next returns the next entry in the packfile index.
@@ -276,3 +310,38 @@ type Entry struct {
276310 CRC32 uint32
277311 Offset uint64
278312}
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