Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions ygot/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,34 @@ func joingNMIPaths(parent *gnmipb.Path, child *gnmipb.Path) *gnmipb.Path {

// pathSpec is a wrapper type used to store a set of gNMI paths to which
// a value within a GoStruct corresponds to.
//
// NOTE: Once Equal() is called, no more changes must be made to pathSpec;
// otherwise, future calls to Equal() will give the incorrect result.
type pathSpec struct {
// gNMIPaths is the set of gNMI paths that the path represents.
gNMIPaths []*gnmipb.Path
// gNMIPathStrs is the set of gNMI paths that the path represents as strings.
gNMIPathStrs map[string]struct{}
}

func (p *pathSpec) populateStrs() {
if p == nil {
return
}

if p.gNMIPathStrs != nil {
return
}

p.gNMIPathStrs = map[string]struct{}{}
for _, path := range p.gNMIPaths {
str, err := PathToString(path)
if err != nil {
p.gNMIPathStrs = nil
return
}
p.gNMIPathStrs[str] = struct{}{}
}
}

// Equal compares two pathSpecs, returning true if all paths within the pathSpec
Expand All @@ -62,6 +87,13 @@ func (p *pathSpec) Equal(o *pathSpec) bool {
return p == o
}

p.populateStrs()
o.populateStrs()

if p.gNMIPathStrs != nil && o.gNMIPathStrs != nil {
return reflect.DeepEqual(p.gNMIPathStrs, o.gNMIPathStrs)
}

for _, path := range p.gNMIPaths {
var found bool
for _, otherPath := range o.gNMIPaths {
Expand Down
20 changes: 16 additions & 4 deletions ygot/schema_tests/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package schematest

import (
"fmt"
"io/ioutil"
"reflect"
"testing"
Expand Down Expand Up @@ -591,8 +592,11 @@ func TestNotificationOutput(t *testing.T) {
}
}

func getBenchmarkDevice() *exampleoc.Device {
intfs := []string{"eth0", "eth1", "eth2", "eth3"}
func getBenchmarkDevice(n int) *exampleoc.Device {
var intfs []string
for i := 0; i < n; i++ {
intfs = append(intfs, fmt.Sprintf("eth%d", i))
}
d := &exampleoc.Device{}
for _, intf := range intfs {
d.GetOrCreateInterface(intf)
Expand All @@ -603,7 +607,7 @@ func getBenchmarkDevice() *exampleoc.Device {
}

func BenchmarkNotificationOutput(b *testing.B) {
d := getBenchmarkDevice()
d := getBenchmarkDevice(4)
b.ResetTimer()
for i := 0; i != b.N; i++ {
if _, err := ygot.TogNMINotifications(d, 0, ygot.GNMINotificationsConfig{
Expand All @@ -615,7 +619,7 @@ func BenchmarkNotificationOutput(b *testing.B) {
}

func BenchmarkNotificationOutputElement(b *testing.B) {
d := getBenchmarkDevice()
d := getBenchmarkDevice(4)
b.ResetTimer()
for i := 0; i != b.N; i++ {
if _, err := ygot.TogNMINotifications(d, 0, ygot.GNMINotificationsConfig{
Expand All @@ -625,3 +629,11 @@ func BenchmarkNotificationOutputElement(b *testing.B) {
}
}
}

func BenchmarkDiff(b *testing.B) {
d1 := getBenchmarkDevice(1000)
d2 := getBenchmarkDevice(500)
for n := 0; n != b.N; n++ {
ygot.Diff(d1, d2)
}
}