diff options
| author | Jeff Carr <[email protected]> | 2024-11-26 04:34:01 -0600 |
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2024-11-26 04:34:01 -0600 |
| commit | 316bc8ea81200a48b8a7259905720362b512ce2a (patch) | |
| tree | 411251bf71593f7e434f92cd0124108dafe365c6 /refs.sort.go | |
Day 1
Diffstat (limited to 'refs.sort.go')
| -rw-r--r-- | refs.sort.go | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/refs.sort.go b/refs.sort.go new file mode 100644 index 0000000..6080afc --- /dev/null +++ b/refs.sort.go @@ -0,0 +1,166 @@ +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 lock sync.RWMutex + +type RefIterator struct { + sync.RWMutex + + packs []*Ref + index int +} + +// NewRefIterator initializes a new iterator. +func NewRefIterator(packs []*Ref) *RefIterator { + return &RefIterator{packs: packs} +} + +// Scan moves to the next element and returns false if there are no more packs. +func (it *RefIterator) Scan() bool { + if it.index >= len(it.packs) { + return false + } + it.index++ + return true +} + +// Ref returns the current repo. +func (it *RefIterator) Ref() *Ref { + 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.Ref() +// fmt.Println("Ref UUID:", d.Uuid) +// } + +func (r *Refs) All() *RefIterator { + repoPointers := r.selectAllRefs() + + iterator := NewRefIterator(repoPointers) + return iterator +} + +func (r *Refs) SortByName() *RefIterator { + packs := r.selectAllRefs() + + sort.Sort(ByName(packs)) + + iterator := NewRefIterator(packs) + return iterator +} + +// enforces no duplicate package names +func (r *Refs) Append(newP *Ref) bool { + lock.Lock() + defer lock.Unlock() + + for _, p := range r.Refs { + if p.RefName == newP.RefName { + return false + } + } + + r.Refs = append(r.Refs, newP) + return true +} + +// returns time.Duration since last Update() +func (r *Ref) Age(newP *Ref) time.Duration { + t := time.Since(r.Ctime.AsTime()) + return t +} + +// find a package by name +func (r *Refs) FindByName(name string) *Ref { + lock.RLock() + defer lock.RUnlock() + + for _, p := range r.Refs { + if p.RefName == name { + return p + } + } + + return nil +} + +func (r *Refs) Len() int { + lock.RLock() + defer lock.RUnlock() + + return len(r.Refs) +} + +type ByName []*Ref + +func (a ByName) Len() int { return len(a) } +func (a ByName) Less(i, j int) bool { return a[i].RefName < a[j].RefName } +func (a ByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +// safely returns a slice of pointers to the Ref protobufs +func (r *Refs) selectAllRefs() []*Ref { + lock.RLock() + defer lock.RUnlock() + + // Create a new slice to hold pointers to each Ref + var allPacks []*Ref + allPacks = make([]*Ref, len(r.Refs)) + for i, p := range r.Refs { + allPacks[i] = p // Copy pointers for safe iteration + } + + return allPacks +} + +/* +func (r *Refs) UnmergedRefRepos() *RefRepoIterator { + repoPointers := r.selectUnmergedRefRepos() + + sort.Sort(ByName(repoPointers)) + + iterator := NewRefRepoIterator(repoPointers) + + return iterator +} +*/ + +/* +// this sort doesn't really work. I think it forgets to sort the last two +// todo: sort this out. literally +// SelectRefPointers safely returns a slice of pointers to Ref records. +func (r *Refs) selectUnmergedRefs() []*RefRow { + r.RLock() + defer r.RUnlock() + + // Create a new slice to hold pointers to each Ref + // repoPointers := make([]*Ref, len(c.E.Refs)) + var repoPointers []*RefRow + for _, repo := range me.allrepos { + repoPointers = append(repoPointers, repo) // Copy pointers for safe iteration + } + + return repoPointers +} +*/ |
