d2ir: Add Map.CopyBase for better performance

This commit is contained in:
Anmol Sethi 2023-01-21 18:52:33 -08:00
parent ece34aaf01
commit bd7b5c3fc0
No known key found for this signature in database
GPG key ID: 25BC68888A99A8BA
2 changed files with 45 additions and 31 deletions

View file

@ -41,7 +41,7 @@ func (c *compiler) compileScenarios(m *Map) {
parent: sf, parent: sf,
} }
} }
base := m.Copy(sf).(*Map) base := m.CopyBase(sf)
sf.Composite = Overlay(base, sf.Map()) sf.Composite = Overlay(base, sf.Map())
c.compileScenarios(sf.Map()) c.compileScenarios(sf.Map())
c.compileSteps(sf.Map()) c.compileSteps(sf.Map())
@ -66,9 +66,9 @@ func (c *compiler) compileSteps(m *Map) {
var base *Map var base *Map
if i == 0 { if i == 0 {
base = m.Copy(sf).(*Map) base = m.CopyBase(sf)
} else { } else {
base = steps.Fields[i-1].Map().Copy(sf).(*Map) base = steps.Fields[i-1].Map().CopyBase(sf)
} }
sf.Composite = Overlay(base, sf.Map()) sf.Composite = Overlay(base, sf.Map())
c.compileScenarios(sf.Map()) c.compileScenarios(sf.Map())

View file

@ -23,7 +23,7 @@ type Node interface {
Primary() *Scalar Primary() *Scalar
Map() *Map Map() *Map
ast() d2ast.Node AST() d2ast.Node
fmt.Stringer fmt.Stringer
} }
@ -87,11 +87,11 @@ func (n *Map) value() {}
func (n *Array) composite() {} func (n *Array) composite() {}
func (n *Map) composite() {} func (n *Map) composite() {}
func (n *Scalar) String() string { return d2format.Format(n.ast()) } func (n *Scalar) String() string { return d2format.Format(n.AST()) }
func (n *Field) String() string { return d2format.Format(n.ast()) } func (n *Field) String() string { return d2format.Format(n.AST()) }
func (n *Edge) String() string { return d2format.Format(n.ast()) } func (n *Edge) String() string { return d2format.Format(n.AST()) }
func (n *Array) String() string { return d2format.Format(n.ast()) } func (n *Array) String() string { return d2format.Format(n.AST()) }
func (n *Map) String() string { return d2format.Format(n.ast()) } func (n *Map) String() string { return d2format.Format(n.AST()) }
type Scalar struct { type Scalar struct {
parent Node parent Node
@ -121,7 +121,6 @@ type Map struct {
Edges []*Edge `json:"edges"` Edges []*Edge `json:"edges"`
} }
// Copy copies the map m without layers/scenarios/steps.
func (m *Map) Copy(newp Node) Node { func (m *Map) Copy(newp Node) Node {
tmp := *m tmp := *m
m = &tmp m = &tmp
@ -130,9 +129,6 @@ func (m *Map) Copy(newp Node) Node {
pfields := m.Fields pfields := m.Fields
m.Fields = make([]*Field, 0, len(pfields)) m.Fields = make([]*Field, 0, len(pfields))
for _, f := range pfields { for _, f := range pfields {
if hasLayerKeywords(f.Name) != -1 {
continue
}
m.Fields = append(m.Fields, f.Copy(m).(*Field)) m.Fields = append(m.Fields, f.Copy(m).(*Field))
} }
m.Edges = append([]*Edge(nil), m.Edges...) m.Edges = append([]*Edge(nil), m.Edges...)
@ -142,6 +138,24 @@ func (m *Map) Copy(newp Node) Node {
return m return m
} }
// CopyBase copies the map m without layers/scenarios/steps.
func (m *Map) CopyBase(newp Node) *Map {
layers := m.DeleteField("layers")
scenarios := m.DeleteField("scenarios")
steps := m.DeleteField("steps")
m2 := m.Copy(newp).(*Map)
if layers != nil {
m.Fields = append(m.Fields, layers)
}
if scenarios != nil {
m.Fields = append(m.Fields, scenarios)
}
if steps != nil {
m.Fields = append(m.Fields, steps)
}
return m2
}
// Root reports whether the Map is the root of the D2 tree. // Root reports whether the Map is the root of the D2 tree.
func (m *Map) Root() bool { func (m *Map) Root() bool {
return m.parent == nil return m.parent == nil
@ -567,9 +581,9 @@ func (m *Map) ensureField(i int, kp *d2ast.KeyPath, refctx *RefContext) (*Field,
return f.Map().ensureField(i+1, kp, refctx) return f.Map().ensureField(i+1, kp, refctx)
} }
func (m *Map) DeleteField(ida []string) bool { func (m *Map) DeleteField(ida ...string) *Field {
if len(ida) == 0 { if len(ida) == 0 {
return false return nil
} }
s := ida[0] s := ida[0]
@ -580,14 +594,14 @@ func (m *Map) DeleteField(ida []string) bool {
continue continue
} }
if len(rest) == 0 { if len(rest) == 0 {
copy(m.Fields[i:], m.Fields[i+1:]) m.Fields = append(m.Fields[:i], m.Fields[i+1:]...)
return true return f
} }
if f.Map() != nil { if f.Map() != nil {
return f.Map().DeleteField(rest) return f.Map().DeleteField(rest...)
} }
} }
return false return nil
} }
func (m *Map) GetEdges(eid *EdgeID) []*Edge { func (m *Map) GetEdges(eid *EdgeID) []*Edge {
@ -682,11 +696,11 @@ func (m *Map) CreateEdge(eid *EdgeID, refctx *RefContext) (*Edge, error) {
return e, nil return e, nil
} }
func (s *Scalar) ast() d2ast.Node { func (s *Scalar) AST() d2ast.Node {
return s.Value return s.Value
} }
func (f *Field) ast() d2ast.Node { func (f *Field) AST() d2ast.Node {
k := &d2ast.Key{ k := &d2ast.Key{
Key: &d2ast.KeyPath{ Key: &d2ast.KeyPath{
Path: []*d2ast.StringBox{ Path: []*d2ast.StringBox{
@ -696,16 +710,16 @@ func (f *Field) ast() d2ast.Node {
} }
if f.Primary_ != nil { if f.Primary_ != nil {
k.Primary = d2ast.MakeValueBox(f.Primary_.ast().(d2ast.Value)).ScalarBox() k.Primary = d2ast.MakeValueBox(f.Primary_.AST().(d2ast.Value)).ScalarBox()
} }
if f.Composite != nil { if f.Composite != nil {
k.Value = d2ast.MakeValueBox(f.Composite.ast().(d2ast.Value)) k.Value = d2ast.MakeValueBox(f.Composite.AST().(d2ast.Value))
} }
return k return k
} }
func (e *Edge) ast() d2ast.Node { func (e *Edge) AST() d2ast.Node {
astEdge := &d2ast.Edge{} astEdge := &d2ast.Edge{}
astEdge.Src = d2ast.MakeKeyPath(e.ID.SrcPath) astEdge.Src = d2ast.MakeKeyPath(e.ID.SrcPath)
@ -722,27 +736,27 @@ func (e *Edge) ast() d2ast.Node {
} }
if e.Primary_ != nil { if e.Primary_ != nil {
k.Primary = d2ast.MakeValueBox(e.Primary_.ast().(d2ast.Value)).ScalarBox() k.Primary = d2ast.MakeValueBox(e.Primary_.AST().(d2ast.Value)).ScalarBox()
} }
if e.Map_ != nil { if e.Map_ != nil {
k.Value = d2ast.MakeValueBox(e.Map_.ast().(*d2ast.Map)) k.Value = d2ast.MakeValueBox(e.Map_.AST().(*d2ast.Map))
} }
return k return k
} }
func (a *Array) ast() d2ast.Node { func (a *Array) AST() d2ast.Node {
if a == nil { if a == nil {
return nil return nil
} }
astArray := &d2ast.Array{} astArray := &d2ast.Array{}
for _, av := range a.Values { for _, av := range a.Values {
astArray.Nodes = append(astArray.Nodes, d2ast.MakeArrayNodeBox(av.ast().(d2ast.ArrayNode))) astArray.Nodes = append(astArray.Nodes, d2ast.MakeArrayNodeBox(av.AST().(d2ast.ArrayNode)))
} }
return astArray return astArray
} }
func (m *Map) ast() d2ast.Node { func (m *Map) AST() d2ast.Node {
if m == nil { if m == nil {
return nil return nil
} }
@ -753,10 +767,10 @@ func (m *Map) ast() d2ast.Node {
astMap.Range = d2ast.MakeRange(",1:0:0-2:0:0") astMap.Range = d2ast.MakeRange(",1:0:0-2:0:0")
} }
for _, f := range m.Fields { for _, f := range m.Fields {
astMap.Nodes = append(astMap.Nodes, d2ast.MakeMapNodeBox(f.ast().(d2ast.MapNode))) astMap.Nodes = append(astMap.Nodes, d2ast.MakeMapNodeBox(f.AST().(d2ast.MapNode)))
} }
for _, e := range m.Edges { for _, e := range m.Edges {
astMap.Nodes = append(astMap.Nodes, d2ast.MakeMapNodeBox(e.ast().(d2ast.MapNode))) astMap.Nodes = append(astMap.Nodes, d2ast.MakeMapNodeBox(e.AST().(d2ast.MapNode)))
} }
return astMap return astMap
} }