Apply further optimisation to Sets.Merge()

Avoid memory allocation if the merged Sets will be the same as the input.
This commit is contained in:
Bryan Boreham
2018-08-09 09:12:51 +00:00
parent bb7aa19324
commit 4610e2b252
2 changed files with 38 additions and 0 deletions

View File

@@ -105,7 +105,29 @@ func (m Sets) Merge(n Sets) Sets {
}
i, j := 0, 0
loop:
for i < len(m) {
switch {
case j >= len(n):
return m
case m[i].key == n[j].key:
if !m[i].Value.ContainsSet(n[j].Value) {
break loop
}
i++
j++
case m[i].key < n[j].key:
i++
default:
break loop
}
}
if i >= len(m) && j >= len(n) {
return m
}
out := make([]stringSetEntry, i, len(m))
copy(out, m[:i])
for i < len(m) {
switch {

View File

@@ -36,6 +36,22 @@ func (s StringSet) Contains(str string) bool {
return i < len(s) && s[i] == str
}
// ContainsSet returns true if the string set includes all strings in the other set
func (s StringSet) ContainsSet(b StringSet) bool {
i, j := 0, 0
for i < len(s) && j < len(b) {
if s[i] == b[j] {
i++
j++
} else if s[i] < b[j] {
i++
} else {
return false
}
}
return j == len(b)
}
// Intersection returns the intersections of a and b
func (s StringSet) Intersection(b StringSet) StringSet {
result, i, j := emptyStringSet, 0, 0