add graph caching and garbage collection

This commit is contained in:
2023-01-29 23:37:25 -08:00
parent 0390abcfeb
commit 59aa42b563
3 changed files with 81 additions and 12 deletions

View File

@@ -1,7 +1,6 @@
package main package main
import ( import (
"math/rand"
"net/http" "net/http"
"strconv" "strconv"
"time" "time"
@@ -14,17 +13,10 @@ import (
type DayCount [366]int type DayCount [366]int
func init() {
rand.Seed(time.Now().UnixMilli())
}
func main() { func main() {
r := mux.NewRouter() r := mux.NewRouter()
r.HandleFunc("/weekly.svg", func(w http.ResponseWriter, r *http.Request) { r.HandleFunc("/weekly.svg", func(w http.ResponseWriter, r *http.Request) {
freq := []int{} freq := []int{}
for i := 0; i < 7; i++ {
freq = append(freq, rand.Int())
}
w.Header().Add("Content-Type", "text/html") w.Header().Add("Content-Type", "text/html")
svg := svg.GetWeekSVG(freq) svg := svg.GetWeekSVG(freq)
svg.WriteTo(w) svg.WriteTo(w)

View File

@@ -1,9 +1,13 @@
package commits package commits
import ( import (
"crypto/md5"
"errors" "errors"
"fmt"
"os" "os"
"regexp" "regexp"
"sort"
"strings"
"sync" "sync"
"time" "time"
@@ -16,6 +20,71 @@ import (
type Repo git.Repository type Repo git.Repository
var (
mapTex sync.RWMutex
hashCache map[int]map[string]map[string]types.ExpYearFreq
)
func init() {
hashCache = make(map[int]map[string]map[string]types.ExpYearFreq)
}
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.YearFreq, bool) {
a := hashSlice(authors)
r := hashSlice(repoPaths)
mapTex.RLock()
defer mapTex.RUnlock()
if m1, ok := hashCache[year]; !ok {
return types.YearFreq{}, false
} else {
if m2, ok := m1[a]; !ok {
return types.YearFreq{}, false
} else {
if freq, ok := m2[r]; !ok {
return types.YearFreq{}, false
} else {
if freq.Created.Before(time.Now().Add(-15 * time.Minute)) {
return types.YearFreq{}, false
} else {
return freq.YearFreq, true
}
}
}
}
}
func CacheGraph(year int, authors, repoPaths []string, freq types.YearFreq) {
a := hashSlice(authors)
r := hashSlice(repoPaths)
mapTex.Lock()
defer mapTex.Unlock()
if _, ok := hashCache[year]; !ok {
hashCache[year] = make(map[string]map[string]types.ExpYearFreq)
}
if _, ok := hashCache[year][a]; !ok {
hashCache[year][a] = make(map[string]types.ExpYearFreq)
}
hashCache[year][a][r] = types.ExpYearFreq{YearFreq: freq, Created: time.Now()}
go func() {
time.Sleep(time.Minute * 15)
mapTex.Lock()
defer mapTex.Unlock()
delete(hashCache[year][a], r)
}()
}
func GlobalFrequencyChan(year int, authors []string) (types.YearFreq, error) { func GlobalFrequencyChan(year int, authors []string) (types.YearFreq, error) {
yearLength := 365 yearLength := 365
if year%4 == 0 { if year%4 == 0 {
@@ -26,6 +95,10 @@ func GlobalFrequencyChan(year int, authors []string) (types.YearFreq, error) {
return types.YearFreq{}, err return types.YearFreq{}, err
} }
paths := mrconf.GetRepoPaths() paths := mrconf.GetRepoPaths()
cache, ok := GetCachedGraph(year, authors, paths)
if ok {
return cache, nil
}
outChan := make(chan types.Commit, 10) outChan := make(chan types.Commit, 10)
var wg sync.WaitGroup var wg sync.WaitGroup
for _, p := range paths { for _, p := range paths {
@@ -55,7 +128,7 @@ func GlobalFrequencyChan(year int, authors []string) (types.YearFreq, error) {
close(outChan) close(outChan)
}() }()
freq := YearFreqFromChan(outChan, year) freq := YearFreqFromChan(outChan, year)
CacheGraph(year, authors, paths, freq)
return freq, nil return freq, nil
} }

View File

@@ -16,6 +16,10 @@ type (
} }
DataSet map[time.Time]WorkDay DataSet map[time.Time]WorkDay
YearFreq []int YearFreq []int
ExpYearFreq struct {
YearFreq YearFreq
Created time.Time
}
WorkDay struct { WorkDay struct {
Day time.Time `json:"day"` Day time.Time `json:"day"`
Count int `json:"count"` Count int `json:"count"`