From a43f52044f13225bbc7df1649c6daa3d5f4d4bdb Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Sat, 15 Feb 2025 19:00:46 -0600 Subject: [PATCH] Notes added by 'git notes append' --- 5d0f74360f7be1c5f7adced242e0a8e613fdcfd1 | 296 +++++++++++++++++++++++ 1 file changed, 296 insertions(+) diff --git a/5d0f74360f7be1c5f7adced242e0a8e613fdcfd1 b/5d0f74360f7be1c5f7adced242e0a8e613fdcfd1 index 5b136d1..f73c450 100644 --- a/5d0f74360f7be1c5f7adced242e0a8e613fdcfd1 +++ b/5d0f74360f7be1c5f7adced242e0a8e613fdcfd1 @@ -2526,3 +2526,299 @@ func file_repo_proto_init() { } // `autogen:repo.sort.pb.go` + +// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT. +// This file was autogenerated with autogenpb v0.0.49-2-g9a0e4a6 2025.02.01_0732 +// go install go.wit.com/apps/autogenpb@latest +// +// define which structs (messages) you want to use in the .proto file +// Then sort.pb.go and marshal.pb.go files are autogenerated +// +// autogenpb uses it and has an example .proto file with instructions +// + +package gitpb + +import ( + "fmt" + "sort" + "sync" +) + +// a simple global lock +var repoMu sync.RWMutex + +func (x *Repos) fixUuid() { + if x == nil { + return + } + if x.Uuid == "8daaeba1-fb1f-4762-ae6e-95a55d352673" { + return + } + x.Uuid = "8daaeba1-fb1f-4762-ae6e-95a55d352673" + x.Version = "v3 go.wit.com/lib/protobuf/gitpb" +} + +func NewRepos() *Repos { + x := new(Repos) + x.Uuid = "8daaeba1-fb1f-4762-ae6e-95a55d352673" + x.Version = "v3 go.wit.com/lib/protobuf/gitpb" + return x +} + +// START SORT + +// DEFINE THE Repos ITERATOR. +// itializes a new iterator. +func newReposIterator(things []*Repos) *ReposIterator { + return &ReposIterator{things: things} +} + +type ReposIterator struct { + sync.RWMutex // this isn't getting used properly yet? + + things []*Repos + index int +} + +func (it *ReposIterator) Scan() bool { + if it.index >= len(it.things) { + return false + } + it.index++ + return true +} + +// Next() returns the next thing in the array +func (it *ReposIterator) Next() *Repos { + if it.things[it.index-1] == nil { + fmt.Println("Next() error in ReposIterator", it.index) + } + return it.things[it.index-1] +} + +// END DEFINE THE ITERATOR + +// DEFINE THE Repo ITERATOR. +// itializes a new iterator. +func newRepoIterator(things []*Repo) *RepoIterator { + return &RepoIterator{things: things} +} + +type RepoIterator struct { + sync.RWMutex // this isn't getting used properly yet? + + things []*Repo + index int +} + +func (it *RepoIterator) Scan() bool { + if it.index >= len(it.things) { + return false + } + it.index++ + return true +} + +// Next() returns the next thing in the array +func (it *RepoIterator) Next() *Repo { + if it.things[it.index-1] == nil { + fmt.Println("Next() error in RepoIterator", it.index) + } + return it.things[it.index-1] +} + +// END DEFINE THE ITERATOR + +// DEFINE THE GitTimes ITERATOR. +// itializes a new iterator. +func newGitTimesIterator(things []*GitTimes) *GitTimesIterator { + return &GitTimesIterator{things: things} +} + +type GitTimesIterator struct { + sync.RWMutex // this isn't getting used properly yet? + + things []*GitTimes + index int +} + +func (it *GitTimesIterator) Scan() bool { + if it.index >= len(it.things) { + return false + } + it.index++ + return true +} + +// Next() returns the next thing in the array +func (it *GitTimesIterator) Next() *GitTimes { + if it.things[it.index-1] == nil { + fmt.Println("Next() error in GitTimesIterator", it.index) + } + return it.things[it.index-1] +} + +// END DEFINE THE ITERATOR + +// DEFINE THE GoInfo ITERATOR. +// itializes a new iterator. +func newGoInfoIterator(things []*GoInfo) *GoInfoIterator { + return &GoInfoIterator{things: things} +} + +type GoInfoIterator struct { + sync.RWMutex // this isn't getting used properly yet? + + things []*GoInfo + index int +} + +func (it *GoInfoIterator) Scan() bool { + if it.index >= len(it.things) { + return false + } + it.index++ + return true +} + +// Next() returns the next thing in the array +func (it *GoInfoIterator) Next() *GoInfo { + if it.things[it.index-1] == nil { + fmt.Println("Next() error in GoInfoIterator", it.index) + } + return it.things[it.index-1] +} + +// END DEFINE THE ITERATOR + +// sort struct by FullPath +type RepoFullPath []*Repo + +func (a RepoFullPath) Len() int { return len(a) } +func (a RepoFullPath) Less(i, j int) bool { return a[i].FullPath < a[j].FullPath } +func (a RepoFullPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +// safely returns a slice of pointers to the FRUIT protobufs +func (x *Repos) allRepos() []*Repo { + repoMu.RLock() + defer repoMu.RUnlock() + + // Create a new slice to hold pointers to each FRUIT + var tmp []*Repo + tmp = make([]*Repo, len(x.Repos)) + for i, p := range x.Repos { + tmp[i] = p // Copy pointers for safe iteration + } + + return tmp +} + +// safely returns a slice of pointers to the Repo protobufs +func (x *Repos) selectAllRepos() []*Repo { + repoMu.RLock() + defer repoMu.RUnlock() + + // Create a new slice to hold pointers to each Repo + var tmp []*Repo + tmp = make([]*Repo, len(x.Repos)) + for i, p := range x.Repos { + tmp[i] = p // Copy pointers for safe iteration + } + + return tmp +} +func (x *Repos) SortByFullPath() *RepoIterator { + // copy the pointers as fast as possible. + things := x.selectAllRepos() + + // todo: try slices.SortFunc() instead to see what happens + sort.Sort(RepoFullPath(things)) + // slices.SortFunc(things, func(a, b *Repos) bool { + // return a.FullPath < b.FullPath // Sort by ??. let the compiler work it out?? + // }) + return newRepoIterator(things) +} + +// END SORT + +func (x *Repos) Len() int { + repoMu.RLock() + defer repoMu.RUnlock() + + return len(x.Repos) +} + +// just a simple Append() shortcut (but still uses the mutex lock) +func (x *Repos) Append(y *Repo) { + repoMu.Lock() + defer repoMu.Unlock() + + x.Repos = append(x.Repos, y) +} + +func (x *Repos) All() *RepoIterator { + RepoPointers := x.selectAllRepos() + + iterator := newRepoIterator(RepoPointers) + return iterator +} + +func (x *Repos) Delete(y *Repo) bool { + repoMu.Lock() + defer repoMu.Unlock() + + for i, _ := range x.Repos { + if x.Repos[i] == y { + x.Repos[i] = x.Repos[len(x.Repos)-1] + x.Repos = x.Repos[:len(x.Repos)-1] + return true + } + } + return false +} + +// lookup a Repos by the FullPath +func (x *Repos) FindByFullPath(s string) *Repo { + if x == nil { + return nil + } + + repoMu.RLock() + defer repoMu.RUnlock() + + for i, _ := range x.Repos { + if x.Repos[i].FullPath == s { + return x.Repos[i] + } + } + return nil +} + +func (x *Repos) DeleteByFullPath(s string) bool { + repoMu.Lock() + defer repoMu.Unlock() + + for i, _ := range x.Repos { + if x.Repos[i].FullPath == s { + x.Repos[i] = x.Repos[len(x.Repos)-1] + x.Repos = x.Repos[:len(x.Repos)-1] + return true + } + } + return false +} + +func (x *Repos) AppendByFullPath(y *Repo) bool { + repoMu.Lock() + defer repoMu.Unlock() + + for _, p := range x.Repos { + if p.FullPath == y.FullPath { + return false + } + } + + x.Repos = append(x.Repos, y) + return true +}