diff options
| author | Jeff Carr <[email protected]> | 2024-11-20 09:31:24 -0600 |
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2024-11-20 09:31:24 -0600 |
| commit | 35a2db858f1635f947c2b5f9bbfe9bb64ef7a472 (patch) | |
| tree | 95eb14b030eeb7f5899ce300a3cfc7fed6338651 /repos.go | |
Day 1v0.0.1
Diffstat (limited to 'repos.go')
| -rw-r--r-- | repos.go | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/repos.go b/repos.go new file mode 100644 index 0000000..07ee8e2 --- /dev/null +++ b/repos.go @@ -0,0 +1,134 @@ +package forgepb + +// TODO: autogen this? (probably not feasible. need go-arglike tricks in proto) + +import ( + "fmt" + "os" + "sort" + sync "sync" + "time" +) + +// bad global lock until I figure out some other plan +var reposLock sync.RWMutex + +type RepoIterator struct { + sync.RWMutex + + packs []*Repo + index int +} + +// NewRepoIterator initializes a new iterator. +func NewRepoIterator(packs []*Repo) *RepoIterator { + return &RepoIterator{packs: packs} +} + +// Scan moves to the next element and returns false if there are no more packs. +func (it *RepoIterator) Scan() bool { + if it.index >= len(it.packs) { + return false + } + it.index++ + return true +} + +// Repo returns the current repo. +func (it *RepoIterator) Repo() *Repo { + 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.Repo() +// fmt.Println("Repo UUID:", d.Uuid) +// } + +func (r *Repos) All() *RepoIterator { + repoPointers := r.selectAllRepos() + + iterator := NewRepoIterator(repoPointers) + return iterator +} + +func (r *Repos) SortByName() *RepoIterator { + packs := r.selectAllRepos() + + sort.Sort(ByRepoName(packs)) + + iterator := NewRepoIterator(packs) + return iterator +} + +// enforces no duplicate repo names +func (r *Repos) Append(newP *Repo) bool { + reposLock.Lock() + defer reposLock.Unlock() + + for _, p := range r.Repos { + if p.Name == newP.Name { + return false + } + } + + r.Repos = append(r.Repos, newP) + return true +} + +// returns time.Duration since last Update() +func (r *Repo) Age(newP *Repo) time.Duration { + t := time.Since(r.Verstamp.AsTime()) + return t +} + +// find a repo by name +func (r *Repos) FindByName(name string) *Repo { + reposLock.RLock() + defer reposLock.RUnlock() + + for _, p := range r.Repos { + if p.Name == name { + return p + } + } + + return nil +} + +func (r *Repos) Len() int { + reposLock.RLock() + defer reposLock.RUnlock() + + return len(r.Repos) +} + +type ByRepoName []*Repo + +func (a ByRepoName) Len() int { return len(a) } +func (a ByRepoName) Less(i, j int) bool { return a[i].Name < a[j].Name } +func (a ByRepoName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +// safely returns a slice of pointers to the Repo protobufs +func (r *Repos) selectAllRepos() []*Repo { + reposLock.RLock() + defer reposLock.RUnlock() + + // Create a new slice to hold pointers to each Repo + var allPacks []*Repo + allPacks = make([]*Repo, len(r.Repos)) + for i, p := range r.Repos { + allPacks[i] = p // Copy pointers for safe iteration + } + + return allPacks +} |
