From e67613830e63de491a07eec2155bc802a2d12388 Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Mon, 13 Jun 2016 17:13:55 -0700 Subject: [PATCH] auth: fix remove subset when there are equal ranges --- auth/range_perm_cache.go | 24 ++++++++++++++++++++---- auth/range_perm_cache_test.go | 10 ++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/auth/range_perm_cache.go b/auth/range_perm_cache.go index a3b2ebea9..e5525cd4b 100644 --- a/auth/range_perm_cache.go +++ b/auth/range_perm_cache.go @@ -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. +// If there are equal ranges, removeSubsetRangePerms only keeps one of them. func removeSubsetRangePerms(perms []*rangePerm) []*rangePerm { // TODO(mitake): currently it is O(n^2), we need a better algorithm newp := make([]*rangePerm, 0) for i := range perms { - subset := false + skip := false for j := range perms { - if i != j && isSubset(perms[i], perms[j]) { - subset = true + if i == j { + 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 } } - if subset { + if skip { continue } diff --git a/auth/range_perm_cache_test.go b/auth/range_perm_cache_test.go index 7f7dff6e3..b5451efa3 100644 --- a/auth/range_perm_cache_test.go +++ b/auth/range_perm_cache_test.go @@ -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("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 {