aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-12-08 11:52:36 +0100
committerDmitry Vyukov <dvyukov@google.com>2020-12-09 09:22:14 +0100
commit716504e0fe9b764e14d4a373dd9b6a1c67d3ce7b (patch)
tree9c9fba7c65fb4c0578cd14c3c7482204db29173d /pkg
parent56ac1612a828a3e25e08d49094c9e5a8b2dcb60c (diff)
pkg/cover: add MergeDiff method
Will be used in the next patch.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/cover/cover.go19
-rw-r--r--pkg/cover/cover_test.go64
2 files changed, 83 insertions, 0 deletions
diff --git a/pkg/cover/cover.go b/pkg/cover/cover.go
index 1fe63e3ad..40c806fd7 100644
--- a/pkg/cover/cover.go
+++ b/pkg/cover/cover.go
@@ -17,6 +17,25 @@ func (cov *Cover) Merge(raw []uint32) {
}
}
+// Merge merges raw into coverage and returns newly added PCs. Overwrites/mutates raw.
+func (cov *Cover) MergeDiff(raw []uint32) []uint32 {
+ c := *cov
+ if c == nil {
+ c = make(Cover)
+ *cov = c
+ }
+ n := 0
+ for _, pc := range raw {
+ if _, ok := c[pc]; ok {
+ continue
+ }
+ c[pc] = struct{}{}
+ raw[n] = pc
+ n++
+ }
+ return raw[:n]
+}
+
func (cov Cover) Serialize() []uint32 {
res := make([]uint32, 0, len(cov))
for pc := range cov {
diff --git a/pkg/cover/cover_test.go b/pkg/cover/cover_test.go
new file mode 100644
index 000000000..7244ca186
--- /dev/null
+++ b/pkg/cover/cover_test.go
@@ -0,0 +1,64 @@
+// Copyright 2020 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package cover
+
+import (
+ "fmt"
+ "sort"
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+)
+
+func TestMergeDiff(t *testing.T) {
+ type Test struct {
+ init []uint32
+ merge []uint32
+ diff []uint32
+ result []uint32
+ }
+ tests := []Test{
+ {
+ init: nil,
+ merge: nil,
+ diff: nil,
+ result: []uint32{},
+ },
+ {
+ init: []uint32{0, 1, 3, 4},
+ merge: nil,
+ diff: nil,
+ result: []uint32{0, 1, 3, 4},
+ },
+ {
+ init: nil,
+ merge: []uint32{0, 1, 3, 4},
+ diff: []uint32{0, 1, 3, 4},
+ result: []uint32{0, 1, 3, 4},
+ },
+ {
+ init: []uint32{0, 1, 3, 4},
+ merge: []uint32{4, 7, 1, 9},
+ diff: []uint32{7, 9},
+ result: []uint32{0, 1, 3, 4, 7, 9},
+ },
+ }
+ for i, test := range tests {
+ t.Run(fmt.Sprint(i), func(t *testing.T) {
+ var cov Cover
+ cov.Merge(test.init)
+ diff := cov.MergeDiff(test.merge)
+ if res := cmp.Diff(test.diff, diff); res != "" {
+ t.Fatalf("MergeDiff result is wrong: %v", res)
+ }
+ result := cov.Serialize()
+ sort.Slice(result, func(i, j int) bool {
+ return result[i] < result[j]
+ })
+ if res := cmp.Diff(test.result, result); res != "" {
+ t.Fatalf("resulting coverage is wrong: %v", res)
+ }
+ })
+ }
+}