diff options
Diffstat (limited to 'godep.sort.go')
| -rw-r--r-- | godep.sort.go | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/godep.sort.go b/godep.sort.go new file mode 100644 index 0000000..edba531 --- /dev/null +++ b/godep.sort.go @@ -0,0 +1,149 @@ +package gitpb + +// this is becoming a standard format +// todo: autogenerate this from the .proto file? + +import ( + "fmt" + "os" + "sort" + sync "sync" + "time" +) + +// bad global lock until I figure out some other plan +var godeplock sync.RWMutex + +type GoDepIterator struct { + sync.RWMutex + + packs []*GoDep + index int +} + +// NewGoDepGoDepIterator initializes a new iterator. +func NewGoDepIterator(packs []*GoDep) *GoDepIterator { + return &GoDepIterator{packs: packs} +} + +// Scan moves to the next element and returns false if there are no more packs. +func (it *GoDepIterator) Scan() bool { + if it.index >= len(it.packs) { + return false + } + it.index++ + return true +} + +// GoDep returns the current repo. +func (it *GoDepIterator) GoDep() *GoDep { + if it.packs[it.index-1] == nil { + for i, d := range it.packs { + fmt.Println("i =", i, d) + } + fmt.Println("len =", len(it.packs)) + fmt.Println("repo == nil", it.index, it.index-1) + os.Exit(-1) + } + return it.packs[it.index-1] +} + +// Use Scan() in a loop, similar to a while loop +// +// for iterator.Scan() { +// d := iterator.GoDep() +// fmt.Println("GoDep UUID:", d.Uuid) +// } + +func (r *GoDeps) All() *GoDepIterator { + repoPointers := r.selectAllGoDeps() + + iterator := NewGoDepIterator(repoPointers) + return iterator +} + +func (r *GoDeps) SortByName() *GoDepIterator { + packs := r.selectAllGoDeps() + + sort.Sort(GoDepByPath(packs)) + + iterator := NewGoDepIterator(packs) + return iterator +} + +// enforces no duplicate package names +func (r *GoDeps) Append(newP *GoDep) bool { + refslock.Lock() + defer refslock.Unlock() + + for _, p := range r.GoDeps { + if p.GoPath == newP.GoPath { + return false + } + } + + r.GoDeps = append(r.GoDeps, newP) + return true +} + +// returns time.Duration since last Update() +func (r *GoDep) Age(newP *GoDep) time.Duration { + t := time.Since(r.Ctime.AsTime()) + return t +} + +// find a dependancy by the go path +func (r *GoDeps) FindByPath(gopath string) *GoDep { + refslock.RLock() + defer refslock.RUnlock() + + for _, p := range r.GoDeps { + if p.GoPath == gopath { + return p + } + } + + return nil +} + +func (r *GoDeps) Len() int { + refslock.RLock() + defer refslock.RUnlock() + + return len(r.GoDeps) +} + +type GoDepByPath []*GoDep + +func (a GoDepByPath) Len() int { return len(a) } +func (a GoDepByPath) Less(i, j int) bool { return a[i].GoPath < a[j].GoPath } +func (a GoDepByPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +// safely returns a slice of pointers to the GoDep protobufs +func (r *GoDeps) selectAllGoDeps() []*GoDep { + refslock.RLock() + defer refslock.RUnlock() + + // Create a new slice to hold pointers to each GoDep + var allPacks []*GoDep + allPacks = make([]*GoDep, len(r.GoDeps)) + for i, p := range r.GoDeps { + allPacks[i] = p // Copy pointers for safe iteration + } + + return allPacks +} + +func (all *GoDeps) DeleteByHash(hash string) *GoDep { + refslock.Lock() + defer refslock.Unlock() + + for i, _ := range all.GoDeps { + if all.GoDeps[i].Hash == hash { + all.GoDeps[i] = all.GoDeps[len(all.GoDeps)-1] + all.GoDeps = all.GoDeps[:len(all.GoDeps)-1] + return nil + } + } + return nil +} |
