auth: fix remove subset when there are equal ranges

This commit is contained in:
Xiang Li 2016-06-13 17:13:55 -07:00
parent a26ebfb675
commit e67613830e
2 changed files with 30 additions and 4 deletions

View File

@ -38,22 +38,38 @@ func isSubset(a, b *rangePerm) bool {
} }
} }
func isRangeEqual(a, b *rangePerm) bool {
return bytes.Equal(a.begin, b.begin) && bytes.Equal(a.end, b.end)
}
// removeSubsetRangePerms removes any rangePerms that are subsets of other rangePerms. // removeSubsetRangePerms removes any rangePerms that are subsets of other rangePerms.
// If there are equal ranges, removeSubsetRangePerms only keeps one of them.
func removeSubsetRangePerms(perms []*rangePerm) []*rangePerm { func removeSubsetRangePerms(perms []*rangePerm) []*rangePerm {
// TODO(mitake): currently it is O(n^2), we need a better algorithm // TODO(mitake): currently it is O(n^2), we need a better algorithm
newp := make([]*rangePerm, 0) newp := make([]*rangePerm, 0)
for i := range perms { for i := range perms {
subset := false skip := false
for j := range perms { for j := range perms {
if i != j && isSubset(perms[i], perms[j]) { if i == j {
subset = true continue
}
if isRangeEqual(perms[i], perms[j]) {
// if ranges are equal, we only keep the first range.
if i > j {
skip = true
break
}
} else if isSubset(perms[i], perms[j]) {
// if a range is a strict subset of the other one, we skip the subset.
skip = true
break break
} }
} }
if subset { if skip {
continue continue
} }

View File

@ -108,6 +108,16 @@ func TestGetMergedPerms(t *testing.T) {
[]*rangePerm{{[]byte("a"), []byte("")}, {[]byte("b"), []byte("c")}, {[]byte("b"), []byte("")}, {[]byte("c"), []byte("")}, {[]byte("d"), []byte("")}}, []*rangePerm{{[]byte("a"), []byte("")}, {[]byte("b"), []byte("c")}, {[]byte("b"), []byte("")}, {[]byte("c"), []byte("")}, {[]byte("d"), []byte("")}},
[]*rangePerm{{[]byte("a"), []byte("")}, {[]byte("b"), []byte("c")}, {[]byte("d"), []byte("")}}, []*rangePerm{{[]byte("a"), []byte("")}, {[]byte("b"), []byte("c")}, {[]byte("d"), []byte("")}},
}, },
// duplicate ranges
{
[]*rangePerm{{[]byte("a"), []byte("f")}, {[]byte("a"), []byte("f")}},
[]*rangePerm{{[]byte("a"), []byte("f")}},
},
// duplicate keys
{
[]*rangePerm{{[]byte("a"), []byte("")}, {[]byte("a"), []byte("")}, {[]byte("a"), []byte("")}},
[]*rangePerm{{[]byte("a"), []byte("")}},
},
} }
for i, tt := range tests { for i, tt := range tests {