Skip to content

Commit

Permalink
Merge pull request #29 from LeoVie/caching
Browse files Browse the repository at this point in the history
Cache normalized files
  • Loading branch information
LeoVie authored Sep 14, 2022
2 parents dd0b79f + f19e18f commit 56b3df1
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 3 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ build/*
!build/.gitkeep
_testdata/generated/reports/*
!_testdata/generated/reports/.gitkeep
_testdata/xdry.log
_testdata/xdry.log
xdry-cache_*.json
/xdry.json
/xdry.log
3 changes: 2 additions & 1 deletion _testdata/xdry_1.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"level-1": 10,
"level-2": 20
},
"logPath": "%pwd%/test/_testdata/xdry.log"
"logPath": "%pwd%/test/_testdata/xdry.log",
"cacheDirectory": "%pwd%/test/_testdata/cache"
},
"directories": [
"%pwd%/test/_testdata/php",
Expand Down
2 changes: 2 additions & 0 deletions _testdata/xdry_minimal.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
86 changes: 86 additions & 0 deletions src/internal/cache/cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package cache

import (
"encoding/json"
"errors"
"io/ioutil"
"os"
"x-dry-go/src/internal/structs"
)

type FileCache struct {
Path string
Items map[string]structs.File `json:"items"`
}

func InitOrReadCache(path string) (*FileCache, error) {
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
return initCache(path)
}

return readFileCache(path)
}

func initCache(path string) (*FileCache, error) {
cache := FileCache{
Path: path,
Items: make(map[string]structs.File),
}

jsonFile, err := json.MarshalIndent(cache, "", " ")
if err != nil {
return nil, err
}

err = ioutil.WriteFile(cache.Path, jsonFile, 0644)
if err != nil {
return nil, err
}

return &cache, nil
}

func readFileCache(path string) (*FileCache, error) {
var cache FileCache

jsonFile, err := os.Open(path)
if err != nil {
return nil, err
}

byteValue, err := ioutil.ReadAll(jsonFile)
if err != nil {
return nil, err
}

err = json.Unmarshal(byteValue, &cache)
if err != nil {
return nil, err
}

return &cache, nil
}

func Store(cache FileCache, file structs.File) error {
cache.Items[file.Path] = file

jsonFile, err := json.MarshalIndent(cache, "", " ")
if err != nil {
return err
}

err = ioutil.WriteFile(cache.Path, jsonFile, 0644)
if err != nil {
return err
}

return nil
}

func Get(cache FileCache, key string) (*structs.File, error) {
if file, ok := cache.Items[key]; ok {
return &file, nil
}

return nil, errors.New("cache item does not exist")
}
24 changes: 24 additions & 0 deletions src/internal/clone_detect/exact_match_clone_detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"log"
"os"
"path/filepath"
"strconv"
"sync"
"x-dry-go/src/internal/cache"
"x-dry-go/src/internal/cli"
"x-dry-go/src/internal/compare"
"x-dry-go/src/internal/config"
Expand Down Expand Up @@ -158,10 +160,20 @@ func normalizeFiles(
levelNormalizers map[int][]config.Normalizer,
filepaths []string,
) map[string]structs.File {
fileCache, err := cache.InitOrReadCache("xdry-cache_level_" + strconv.Itoa(level) + ".json")

if err != nil {
fmt.Println("Error reading cache")
}

var (
normalizedFilesMutex sync.Mutex
normalizedFiles = make(map[string]structs.File)
)
var (
cacheMutex sync.Mutex
mutexedFileCache = fileCache
)

normalizers, ok := levelNormalizers[level]
if !ok {
Expand All @@ -181,6 +193,15 @@ func normalizeFiles(
wg := &sync.WaitGroup{}

for _, path := range filepaths {
normalizedFile, err := cache.Get(*fileCache, path)
if err == nil {
normalizedFilesMutex.Lock()
normalizedFiles[path] = *normalizedFile
normalizedFilesMutex.Unlock()
bar.Add(1)
continue
}

semaphore <- struct{}{}
wg.Add(1)

Expand All @@ -196,6 +217,9 @@ func normalizeFiles(
normalizedFilesMutex.Lock()
normalizedFiles[path] = normalizedFile
normalizedFilesMutex.Unlock()
cacheMutex.Lock()
cache.Store(*mutexedFileCache, normalizedFile)
cacheMutex.Unlock()

bar.Add(1)

Expand Down
5 changes: 5 additions & 0 deletions src/internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Config struct {
type Settings struct {
MinCloneLengths map[string]int `json:"minCloneLengths"`
LogPath string `json:"logPath"`
CacheDirectory string `json:"cacheDirectory"`
}

type Report struct {
Expand Down Expand Up @@ -91,9 +92,13 @@ func hydrateSettings(config *Config, configPath string, cwd string) {
if config.Settings.LogPath == "" {
config.Settings.LogPath = "xdry.log"
}
if config.Settings.CacheDirectory == "" {
config.Settings.CacheDirectory = "."
}

configDir := path.Dir(configPath)
config.Settings.LogPath = toAbsolutePath(config.Settings.LogPath, configDir, cwd)
config.Settings.CacheDirectory = toAbsolutePath(config.Settings.CacheDirectory, configDir, cwd)
}

func toAbsolutePath(directory string, configDir string, cwd string) string {
Expand Down
29 changes: 28 additions & 1 deletion src/internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ func TestParseConfig(t *testing.T) {
"level-1": 10,
"level-2": 20,
},
LogPath: path.Join(cwd, "test", "_testdata", "xdry.log"),
LogPath: path.Join(cwd, "test", "_testdata", "xdry.log"),
CacheDirectory: path.Join(cwd, "test", "_testdata", "cache"),
},
Directories: []string{
path.Join(cwd, "test", "_testdata", "php"),
Expand All @@ -47,3 +48,29 @@ func TestParseConfig(t *testing.T) {

g.Expect(actual).To(Equal(&want))
}

func TestParseConfigMinimal(t *testing.T) {
g := NewGomegaWithT(t)

cwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}

configPath := path.Join(cwd, "..", "..", "..", "_testdata", "xdry_minimal.json")

want := Config{
Settings: Settings{
MinCloneLengths: nil,
LogPath: path.Join(cwd, "..", "..", "..", "_testdata", "xdry.log"),
CacheDirectory: path.Join(cwd, "..", "..", "..", "_testdata"),
},
Reports: nil,
Directories: nil,
Normalizers: nil,
}

_, actual := ParseConfig(configPath, cwd)

g.Expect(actual).To(Equal(&want))
}

0 comments on commit 56b3df1

Please sign in to comment.