@@ -2,11 +2,13 @@ package storage
22
33import (
44 "errors"
5+ "fmt"
56 "io/ioutil"
67 "log"
78 "os"
89 "path/filepath"
910 "strings"
11+ "sync"
1012
1113 "github.com/Bitspark/go-funk"
1214 "github.com/Bitspark/slang/pkg/core"
@@ -18,9 +20,9 @@ import (
1820var FILE_ENDINGS = []string {".yaml" , ".yml" , ".json" } // Order of endings matters!
1921
2022type FileSystem struct {
21- root string
22- cache map [uuid.UUID ]* core.Blueprint
23- uuids []uuid. UUID
23+ root string
24+ cache map [uuid.UUID ]* core.Blueprint
25+ cacheLock sync. Mutex
2426}
2527
2628type WritableFileSystem struct {
@@ -39,12 +41,22 @@ func cleanPath(p string) string {
3941
4042func NewWritableFileSystem (root string ) * WritableFileSystem {
4143 p := cleanPath (root )
42- return & WritableFileSystem {FileSystem : FileSystem {p , make (map [uuid.UUID ]* core.Blueprint ), nil }}
44+ return & WritableFileSystem {
45+ FileSystem {
46+ p ,
47+ make (map [uuid.UUID ]* core.Blueprint ),
48+ sync.Mutex {},
49+ },
50+ }
4351}
4452
4553func NewReadOnlyFileSystem (root string ) * FileSystem {
4654 p := cleanPath (root )
47- return & FileSystem {p , make (map [uuid.UUID ]* core.Blueprint ), nil }
55+ return & FileSystem {
56+ p ,
57+ make (map [uuid.UUID ]* core.Blueprint ),
58+ sync.Mutex {},
59+ }
4860}
4961
5062func (fs * FileSystem ) Has (opId uuid.UUID ) bool {
@@ -53,44 +65,13 @@ func (fs *FileSystem) Has(opId uuid.UUID) bool {
5365}
5466
5567func (fs * FileSystem ) List () ([]uuid.UUID , error ) {
56- if fs .uuids != nil {
57- return fs .uuids , nil
68+ fmt .Println (">" , fs .root )
69+ fmt .Println (funk .Keys (fs .cache ))
70+ if len (fs .cache ) == 0 {
71+ fs .loadBlueprintFiles ()
5872 }
5973
60- opsFilePathSet := make (map [uuid.UUID ]bool )
61-
62- _ = filepath .Walk (fs .root , func (path string , info os.FileInfo , err error ) error {
63- if err != nil {
64- log .Printf ("cannot read file %s: %s" , path , err )
65- return nil
66- }
67-
68- // Prevent recursive walk. Just read files within fs.root
69- if info .IsDir () && path != fs .root {
70- return filepath .SkipDir
71- }
72-
73- if info .IsDir () ||
74- strings .HasPrefix (info .Name (), "." ) ||
75- ! fs .hasSupportedSuffix (info .Name ()) {
76- return nil
77- }
78-
79- blueprint , err := fs .readBlueprintFile (path )
80-
81- if err != nil {
82- log .Printf ("cannot read file %s: %s" , path , err )
83- return nil
84- }
85-
86- opsFilePathSet [blueprint .Id ] = true
87-
88- return nil
89- })
90-
91- fs .uuids = funk .Keys (opsFilePathSet ).([]uuid.UUID )
92-
93- return fs .List ()
74+ return funk .Keys (fs .cache ).([]uuid.UUID ), nil
9475}
9576
9677func (fs * FileSystem ) Load (opId uuid.UUID ) (* core.Blueprint , error ) {
@@ -103,12 +84,15 @@ func (fs *FileSystem) Load(opId uuid.UUID) (*core.Blueprint, error) {
10384 return nil , err
10485 }
10586
106- fs .cache [opId ], err = fs .readBlueprintFile (blueprintFile )
87+ blueprint , err := fs .readBlueprintFile (blueprintFile )
88+
10789 if err != nil {
10890 return nil , err
10991 }
11092
111- return fs .Load (opId )
93+ fs .cacheThis (blueprint )
94+
95+ return blueprint , nil
11296}
11397
11498func (fs * WritableFileSystem ) Save (blueprint core.Blueprint ) (uuid.UUID , error ) {
@@ -122,8 +106,7 @@ func (fs *WritableFileSystem) Save(blueprint core.Blueprint) (uuid.UUID, error)
122106 return opId , err
123107 }
124108
125- delete (fs .cache , opId )
126- fs .uuids = append (fs .uuids , opId )
109+ fs .cacheThis (& blueprint )
127110
128111 blueprintYaml , err := yaml .Marshal (& blueprint )
129112
@@ -141,19 +124,31 @@ func (fs *WritableFileSystem) Save(blueprint core.Blueprint) (uuid.UUID, error)
141124
142125func (fs * WritableFileSystem ) List () ([]uuid.UUID , error ) {
143126 // force to reload writable/local blueprints
144- fs .clearCache ()
127+ fs .clearCache (nil )
145128 return fs .FileSystem .List ()
146129}
147130
148131func (fs * WritableFileSystem ) Load (opId uuid.UUID ) (* core.Blueprint , error ) {
149132 // force to reload writable/local blueprints
150- delete ( fs .cache , opId )
133+ fs .clearCache ( & opId )
151134 return fs .FileSystem .Load (opId )
152135}
153136
154- func (fs * WritableFileSystem ) clearCache () {
137+ func (fs * FileSystem ) cacheThis (blueprint * core.Blueprint ) {
138+ fs .cacheLock .Lock ()
139+ fs .cache [blueprint .Id ] = blueprint
140+ fs .cacheLock .Unlock ()
141+ }
142+
143+ func (fs * WritableFileSystem ) clearCache (blueprintId * uuid.UUID ) {
144+ fs .cacheLock .Lock ()
145+ if blueprintId != nil {
146+ delete (fs .cache , * blueprintId )
147+ fs .cacheLock .Unlock ()
148+ return
149+ }
155150 fs .cache = make (map [uuid.UUID ]* core.Blueprint )
156- fs .uuids = nil
151+ fs .cacheLock . Unlock ()
157152}
158153
159154func (fs * FileSystem ) hasSupportedSuffix (filePath string ) bool {
@@ -168,6 +163,37 @@ func (fs *FileSystem) getFilePath(opId uuid.UUID) (string, error) {
168163 return utils .FileWithFileEnding (filepath .Join (fs .root , opId .String ()), FILE_ENDINGS )
169164}
170165
166+ func (fs * FileSystem ) loadBlueprintFiles () {
167+ _ = filepath .Walk (fs .root , func (path string , info os.FileInfo , err error ) error {
168+ if err != nil {
169+ log .Printf ("cannot read file %s: %s" , path , err )
170+ return nil
171+ }
172+
173+ // Prevent recursive walk. Just read files within fs.root
174+ if info .IsDir () && path != fs .root {
175+ return filepath .SkipDir
176+ }
177+
178+ if info .IsDir () ||
179+ strings .HasPrefix (info .Name (), "." ) ||
180+ ! fs .hasSupportedSuffix (info .Name ()) {
181+ return nil
182+ }
183+
184+ blueprint , err := fs .readBlueprintFile (path )
185+
186+ if err != nil {
187+ log .Printf ("cannot read file %s: %s" , path , err )
188+ return nil
189+ }
190+
191+ fs .cacheThis (blueprint )
192+
193+ return nil
194+ })
195+ }
196+
171197func (fs * FileSystem ) readBlueprintFile (blueprintFile string ) (* core.Blueprint , error ) {
172198 b , err := ioutil .ReadFile (blueprintFile )
173199 if err != nil {
0 commit comments