mid-merge

This commit is contained in:
2023-01-30 22:32:28 -08:00
parent 62780ba810
commit 38bc9bcf94
5 changed files with 202 additions and 31 deletions

View File

@@ -2,29 +2,22 @@ package main
import ( import (
"fmt" "fmt"
"math/rand"
"time" "time"
"github.com/taigrr/gico/commits" "github.com/taigrr/gico/commits"
"github.com/taigrr/gico/graph/term" "github.com/taigrr/gico/graph/term"
) )
func init() {
rand.Seed(time.Now().UnixMilli())
}
func main() { func main() {
wfreq := []int{} wfreq := []int{}
yd := time.Now().YearDay() yd := time.Now().YearDay()
freq, _ := commits.GlobalFrequency(time.Now().Year(), []string{""}) repoPaths, err := commits.GetMRRepos()
if yd < 7 { if err != nil {
// xfreq, _ := commits.GlobalFrequency(time.Now().Year()-1, []string{""}) panic(err)
} else { }
// TODO fix bug for negative in first week of Jan freq, err := repoPaths.GlobalFrequency(time.Now().Year(), []string{""})
for i := 0; i < 7; i++ { if err != nil {
d := time.Now().YearDay() - 1 - 6 + i panic(err)
wfreq = append(wfreq, freq[d])
}
} }
fmt.Println("week:") fmt.Println("week:")
fmt.Println(term.GetWeekUnicode(wfreq)) fmt.Println(term.GetWeekUnicode(wfreq))

View File

@@ -21,7 +21,11 @@ func main() {
w.Header().Add("Content-Type", "text/html") w.Header().Add("Content-Type", "text/html")
now := time.Now() now := time.Now()
year := now.Year() year := now.Year()
freq, err := commits.GlobalFrequencyChan(year, []string{author}) repoPaths, err := commits.GetMRRepos()
if err != nil {
panic(err)
}
freq, err := repoPaths.FrequencyChan(year, []string{author})
if err != nil { if err != nil {
panic(err) panic(err)
} }
@@ -29,7 +33,7 @@ func main() {
fmt.Println(today) fmt.Println(today)
if today < 6 { if today < 6 {
curYear := year - 1 curYear := year - 1
curFreq, err := commits.GlobalFrequencyChan(curYear, []string{author}) curFreq, err := repoPaths.FrequencyChan(curYear, []string{author})
if err != nil { if err != nil {
panic(err) panic(err)
} }
@@ -53,7 +57,11 @@ func main() {
if err == nil { if err == nil {
year = y year = y
} }
freq, err := commits.GlobalFrequencyChan(year, []string{author}) repoPaths, err := commits.GetMRRepos()
if err != nil {
panic(err)
}
freq, err := repoPaths.FrequencyChan(year, []string{author})
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@@ -1,7 +1,12 @@
package commits package commits
import ( import (
"crypto/md5"
"fmt"
"regexp" "regexp"
"sort"
"strings"
"sync"
"time" "time"
git "github.com/go-git/go-git/v5" git "github.com/go-git/go-git/v5"
@@ -11,30 +16,185 @@ import (
"github.com/taigrr/mg/parse" "github.com/taigrr/mg/parse"
) )
func GlobalFrequency(year int, authors []string) (types.YearFreq, error) { type Repo git.Repository
type RepoSet []string
var (
mapTex sync.RWMutex
hashCache map[int]map[string]map[string]types.ExpFreq
)
func init() {
hashCache = make(map[int]map[string]map[string]types.ExpFreq)
}
func hashSlice(in []string) string {
sort.Strings(in)
sb := strings.Builder{}
for _, s := range in {
sb.WriteString(s)
}
h := md5.New()
h.Write([]byte(sb.String()))
b := h.Sum(nil)
return fmt.Sprintf("%x\n", b)
}
func GetCachedGraph(year int, authors []string, repoPaths []string) (types.Freq, bool) {
a := hashSlice(authors)
r := hashSlice(repoPaths)
mapTex.RLock()
defer mapTex.RUnlock()
if m1, ok := hashCache[year]; !ok {
return types.Freq{}, false
} else {
if m2, ok := m1[a]; !ok {
return types.Freq{}, false
} else {
if freq, ok := m2[r]; !ok {
return types.Freq{}, false
} else {
if freq.Created.Before(time.Now().Add(-15 * time.Minute)) {
return types.Freq{}, false
} else {
return freq.YearFreq, true
}
}
}
}
}
func CacheGraph(year int, authors, repoPaths []string, freq types.Freq) {
a := hashSlice(authors)
r := hashSlice(repoPaths)
mapTex.Lock()
defer mapTex.Unlock()
if _, ok := hashCache[year]; !ok {
hashCache[year] = make(map[string]map[string]types.ExpFreq)
}
if _, ok := hashCache[year][a]; !ok {
hashCache[year][a] = make(map[string]types.ExpFreq)
}
hashCache[year][a][r] = types.ExpFreq{YearFreq: freq, Created: time.Now()}
go func() {
time.Sleep(time.Minute * 15)
mapTex.Lock()
defer mapTex.Unlock()
delete(hashCache[year][a], r)
}()
}
func GetMRRepos() (RepoSet, error) {
mrconf, err := parse.LoadMRConfig()
if err != nil {
return RepoSet{}, err
}
paths := mrconf.GetRepoPaths()
return RepoSet(paths), nil
}
func (paths RepoSet) GetWeekFreq(authors []string) (types.Freq, error) {
now := time.Now()
year := now.Year()
freq, err := paths.FrequencyChan(year, authors)
if err != nil {
return types.Freq{}, err
}
today := now.YearDay() - 1
if today < 6 {
curYear := year - 1
curFreq, err := paths.FrequencyChan(curYear, authors)
if err != nil {
return types.Freq{}, err
}
freq = append(curFreq, freq...)
today += 365
if curYear%4 == 0 {
today++
}
}
week := freq[today-6 : today+1]
return week, nil
}
func (paths RepoSet) FrequencyChan(year int, authors []string) (types.Freq, error) {
yearLength := 365 yearLength := 365
if year%4 == 0 { if year%4 == 0 {
yearLength++ yearLength++
} }
gfreq := make(types.YearFreq, yearLength) cache, ok := GetCachedGraph(year, authors, paths)
mrconf, err := parse.LoadMRConfig() if ok {
if err != nil { return cache, 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)
}()
freq := YearFreqFromChan(outChan, year)
CacheGraph(year, authors, paths, freq)
return freq, nil
}
func YearFreqFromChan(cc chan types.Commit, year int) types.Freq {
yearLength := 365
if year%4 == 0 {
yearLength++
}
freq := make([]int, yearLength)
for commit := range cc {
if commit.TimeStamp.Year() != year {
continue
}
freq[commit.TimeStamp.YearDay()-1]++
}
return freq
}
func (paths RepoSet) GlobalFrequency(year int, authors []string) (types.Freq, error) {
yearLength := 365
if year%4 == 0 {
yearLength++
}
gfreq := make(types.Freq, yearLength)
for _, p := range paths { for _, p := range paths {
repo, err := OpenRepo(p) repo, err := OpenRepo(p)
if err != nil { if err != nil {
return types.YearFreq{}, err return types.Freq{}, err
} }
commits, err := repo.GetCommitSet() commits, err := repo.GetCommitSet()
if err != nil { if err != nil {
return types.YearFreq{}, err return types.Freq{}, err
} }
commits = commits.FilterByYear(year) commits = commits.FilterByYear(year)
commits, err = commits.FilterByAuthorRegex(authors) commits, err = commits.FilterByAuthorRegex(authors)
if err != nil { if err != nil {
return types.YearFreq{}, err return types.Freq{}, err
} }
freq := commits.ToYearFreq() freq := commits.ToYearFreq()
gfreq = gfreq.Merge(freq) gfreq = gfreq.Merge(freq)
@@ -64,7 +224,7 @@ func (repo Repo) GetCommitSet() (CommitSet, error) {
return cs, nil return cs, nil
} }
func (cs CommitSet) ToYearFreq() types.YearFreq { func (cs CommitSet) ToYearFreq() types.Freq {
year := cs.Year year := cs.Year
yearLength := 365 yearLength := 365
if year%4 == 0 { if year%4 == 0 {

View File

@@ -7,6 +7,7 @@ import (
git "github.com/go-git/go-git/v5" git "github.com/go-git/go-git/v5"
"github.com/taigrr/gico/types" "github.com/taigrr/gico/types"
"github.com/taigrr/mg/parse"
) )
type ( type (
@@ -28,3 +29,12 @@ func OpenRepo(directory string) (Repo, error) {
r, err := git.PlainOpenWithOptions(directory, &(git.PlainOpenOptions{DetectDotGit: true})) r, err := git.PlainOpenWithOptions(directory, &(git.PlainOpenOptions{DetectDotGit: true}))
return Repo(*r), err return Repo(*r), err
} }
func GetMRRepos() (RepoSet, error) {
mrconf, err := parse.LoadMRConfig()
if err != nil {
return RepoSet{}, err
}
paths := mrconf.GetRepoPaths()
return RepoSet(paths), nil
}

View File

@@ -14,10 +14,10 @@ type (
Repo string `json:"repo,omitempty"` Repo string `json:"repo,omitempty"`
Path string `json:"path,omitempty"` Path string `json:"path,omitempty"`
} }
DataSet map[time.Time]WorkDay DataSet map[time.Time]WorkDay
YearFreq []int Freq []int
ExpYearFreq struct { ExpFreq struct {
YearFreq YearFreq YearFreq Freq
Created time.Time Created time.Time
} }
WorkDay struct { WorkDay struct {