add LoadSaver for JSON, GOB
diff --git a/cmd/kati/main.go b/cmd/kati/main.go
index 2b1f09f..0b9d30c 100644
--- a/cmd/kati/main.go
+++ b/cmd/kati/main.go
@@ -139,33 +139,38 @@
startTime := time.Now()
if loadGOB != "" {
- g := kati.LoadDepGraph(loadGOB)
+ g, err := kati.GOB.Load(loadGOB)
kati.LogStats("deserialize time: %q", time.Since(startTime))
- return g, nil
+ return g, err
}
if loadJSON != "" {
- g := kati.LoadDepGraphFromJSON(loadJSON)
+ g, err := kati.JSON.Load(loadJSON)
kati.LogStats("deserialize time: %q", time.Since(startTime))
- return g, nil
+ return g, err
}
return kati.Load(req)
}
-func save(g *kati.DepGraph, targets []string) {
+func save(g *kati.DepGraph, targets []string) error {
+ var err error
startTime := time.Now()
if saveGOB != "" {
- kati.DumpDepGraph(g, saveGOB, targets)
+ err = kati.GOB.Save(g, saveGOB, targets)
kati.LogStats("serialize time: %q", time.Since(startTime))
}
if saveJSON != "" {
- kati.DumpDepGraphAsJSON(g, saveJSON, targets)
+ serr := kati.JSON.Save(g, saveJSON, targets)
kati.LogStats("serialize time: %q", time.Since(startTime))
+ if err == nil {
+ err = serr
+ }
}
if useCache && !g.IsCached() {
kati.DumpDepGraphCache(g, targets)
kati.LogStats("serialize time: %q", time.Since(startTime))
}
+ return err
}
func main() {
@@ -244,7 +249,10 @@
kati.LogStats("eager eval command time: %q", time.Since(startTime))
}
- save(g, req.Targets)
+ err = save(g, req.Targets)
+ if err != nil {
+ panic(err)
+ }
if generateNinja {
startTime := time.Now()
diff --git a/depgraph.go b/depgraph.go
index cfc3d6a..043fa92 100644
--- a/depgraph.go
+++ b/depgraph.go
@@ -82,7 +82,7 @@
}
if req.UseCache {
- g := LoadDepGraphCache(req.Makefile, req.Targets)
+ g := loadDepGraphCache(req.Makefile, req.Targets)
if g != nil {
return g, nil
}
@@ -148,3 +148,16 @@
exports: er.exports,
}, nil
}
+
+type Loader interface {
+ Load(string) (*DepGraph, error)
+}
+
+type Saver interface {
+ Save(*DepGraph, string, []string) error
+}
+
+type LoadSaver interface {
+ Loader
+ Saver
+}
diff --git a/serialize.go b/serialize.go
index f97eb8c..cbb10ab 100644
--- a/serialize.go
+++ b/serialize.go
@@ -46,6 +46,17 @@
valueTypeTmpval = 't'
)
+var JSON LoadSaver
+var GOB LoadSaver
+
+func init() {
+ JSON = jsonLoadSaver{}
+ GOB = gobLoadSaver{}
+}
+
+type jsonLoadSaver struct{}
+type gobLoadSaver struct{}
+
func dumpInt(w io.Writer, i int) {
v := int32(i)
err := binary.Write(w, binary.LittleEndian, &v)
@@ -240,27 +251,24 @@
}
}
-func DumpDepGraphAsJSON(g *DepGraph, filename string, roots []string) {
+func (jsonLoadSaver) Save(g *DepGraph, filename string, roots []string) error {
sg := makeSerializableGraph(g, roots)
o, err := json.MarshalIndent(sg, " ", " ")
if err != nil {
- panic(err)
+ return err
}
- f, err2 := os.Create(filename)
- if err2 != nil {
- panic(err2)
- }
- f.Write(o)
- err = f.Close()
- if err != nil {
- panic(err)
- }
-}
-
-func DumpDepGraph(g *DepGraph, filename string, roots []string) {
f, err := os.Create(filename)
if err != nil {
- panic(err)
+ return err
+ }
+ f.Write(o)
+ return f.Close()
+}
+
+func (gobLoadSaver) Save(g *DepGraph, filename string, roots []string) error {
+ f, err := os.Create(filename)
+ if err != nil {
+ return err
}
e := gob.NewEncoder(f)
startTime := time.Now()
@@ -269,10 +277,7 @@
startTime = time.Now()
e.Encode(sg)
LogStats("serialize output time: %q", time.Since(startTime))
- err = f.Close()
- if err != nil {
- panic(err)
- }
+ return f.Close()
}
func cacheFilename(mk string, roots []string) string {
@@ -297,7 +302,7 @@
return
}
}
- DumpDepGraph(g, cacheFile, roots)
+ GOB.Save(g, cacheFile, roots)
}
func deserializeSingleChild(sv serializableVar) Value {
@@ -564,10 +569,10 @@
}
}
-func LoadDepGraphFromJSON(filename string) *DepGraph {
+func (jsonLoadSaver) Load(filename string) (*DepGraph, error) {
f, err := os.Open(filename)
if err != nil {
- panic(err)
+ return nil, err
}
defer f.Close()
@@ -575,15 +580,16 @@
g := serializableGraph{Vars: make(map[string]serializableVar)}
err = d.Decode(&g)
if err != nil {
- panic(err)
+ return nil, err
}
- return deserializeGraph(g)
+ dg := deserializeGraph(g)
+ return dg, nil
}
-func LoadDepGraph(filename string) *DepGraph {
+func (gobLoadSaver) Load(filename string) (*DepGraph, error) {
f, err := os.Open(filename)
if err != nil {
- panic(err)
+ return nil, err
}
defer f.Close()
@@ -591,12 +597,13 @@
g := serializableGraph{Vars: make(map[string]serializableVar)}
err = d.Decode(&g)
if err != nil {
- panic(err)
+ return nil, err
}
- return deserializeGraph(g)
+ dg := deserializeGraph(g)
+ return dg, nil
}
-func LoadDepGraphCache(makefile string, roots []string) *DepGraph {
+func loadDepGraphCache(makefile string, roots []string) *DepGraph {
startTime := time.Now()
defer func() {
LogStats("Cache lookup time: %q", time.Since(startTime))
@@ -608,7 +615,11 @@
return nil
}
- g := LoadDepGraph(filename)
+ g, err := GOB.Load(filename)
+ if err != nil {
+ logAlways("Cache load error: %v", err)
+ return nil
+ }
for _, mk := range g.accessedMks {
if mk.State != fileExists && mk.State != fileNotExists {
panic(fmt.Sprintf("Internal error: broken state: %d", mk.State))