add buffered channel methods

This commit is contained in:
2023-01-28 18:09:39 -08:00
parent dbef522f89
commit 4356613bd4
2 changed files with 110 additions and 1 deletions

View File

@@ -14,7 +14,7 @@ type Repo git.Repository
func main() {
year := time.Now().Year() - 1
authors := []string{"Groot"}
gfreq, err := commits.GlobalFrequency(year, authors)
gfreq, err := commits.GlobalFrequencyChan(year, authors)
if err != nil {
panic(err)
}

View File

@@ -4,6 +4,7 @@ import (
"errors"
"os"
"regexp"
"sync"
"time"
git "github.com/go-git/go-git/v5"
@@ -15,6 +16,53 @@ import (
type Repo git.Repository
func GlobalFrequencyChan(year int, authors []string) (types.YearFreq, error) {
yearLength := 365
if year%4 == 0 {
yearLength++
}
mrconf, err := parse.LoadMRConfig()
if err != nil {
return types.YearFreq{}, err
}
paths := mrconf.GetRepoPaths()
outChan := make(chan types.Commit, 10)
var wg sync.WaitGroup
for _, p := range paths {
wg.Add(1)
go func(path string) {
repo, err := OpenRepo(path)
if err != nil {
return
}
cc, err := repo.GetCommitChan()
if err != nil {
return
}
cc = FilterCChanByYear(cc, year)
cc, err = FilterCChanByAuthor(cc, authors)
if err != nil {
return
}
for c := range cc {
outChan <- c
}
wg.Done()
}(p)
}
go func() {
wg.Wait()
close(outChan)
}()
commitSet := CommitSet{Year: year, Commits: []types.Commit{}}
for c := range outChan {
commitSet.Commits = append(commitSet.Commits, c)
}
freq := commitSet.ToYearFreq()
return freq, nil
}
func GlobalFrequency(year int, authors []string) (types.YearFreq, error) {
yearLength := 365
if year%4 == 0 {
@@ -128,6 +176,67 @@ func (cs CommitSet) FilterByYear(year int) CommitSet {
return newCS
}
func FilterCChanByYear(in chan types.Commit, year int) chan types.Commit {
out := make(chan types.Commit, 30)
go func() {
for commit := range in {
if commit.TimeStamp.Year() == year {
out <- commit
}
}
close(out)
}()
return out
}
func FilterCChanByAuthor(in chan types.Commit, authors []string) (chan types.Commit, error) {
out := make(chan types.Commit, 30)
regSet := [](*regexp.Regexp){}
for _, a := range authors {
r, err := regexp.Compile(a)
if err != nil {
close(out)
return out, err
}
regSet = append(regSet, r)
}
go func() {
for commit := range in {
for _, r := range regSet {
if r.MatchString(commit.Author) {
out <- commit
break
}
}
}
close(out)
}()
return out, nil
}
func (repo Repo) GetCommitChan() (chan types.Commit, error) {
cc := make(chan types.Commit, 30)
r := git.Repository(repo)
ref, err := r.Head()
if err != nil {
return cc, err
}
cIter, err := r.Log(&git.LogOptions{From: ref.Hash()})
if err != nil {
return cc, err
}
go func() {
cIter.ForEach(func(c *object.Commit) error {
ts := c.Author.When
commit := types.Commit{Author: c.Author.Name, Message: c.Message, TimeStamp: ts}
cc <- commit
return nil
})
close(cc)
}()
return cc, nil
}
func (repo Repo) GetCommitSet() (CommitSet, error) {
cs := CommitSet{}
commits := []types.Commit{}