Skip to content

Commit

Permalink
placement: trim patch (#2866)
Browse files Browse the repository at this point in the history
Signed-off-by: disksing <i@disksing.com>
  • Loading branch information
disksing authored Sep 1, 2020
1 parent df2344f commit 6322b8e
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 18 deletions.
46 changes: 28 additions & 18 deletions server/schedule/placement/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ func (c *ruleConfig) setRule(r *Rule) {
c.rules[r.Key()] = r
}

func (c *ruleConfig) setGroup(g *RuleGroup) {
c.groups[g.ID] = g
}

func (c *ruleConfig) getGroup(id string) *RuleGroup {
if g, ok := c.groups[id]; ok {
return g
}
return &RuleGroup{ID: id}
}

func (c *ruleConfig) beginPatch() *ruleConfigPatch {
return &ruleConfigPatch{
c: c,
Expand All @@ -79,24 +90,12 @@ type ruleConfigPatch struct {
mut *ruleConfig // record all to-commit rules and groups
}

func (p *ruleConfigPatch) getRule(key [2]string) *Rule {
if r, ok := p.mut.rules[key]; ok {
return r
}
return p.c.rules[key]
}

func (p *ruleConfigPatch) setRule(r *Rule) {
if old := p.getRule(r.Key()); !jsonEquals(old, r) {
p.mut.rules[r.Key()] = r
}
p.mut.rules[r.Key()] = r
}

func (p *ruleConfigPatch) deleteRule(group, id string) {
key := [2]string{group, id}
if old := p.getRule(key); old != nil {
p.mut.rules[key] = nil
}
p.mut.rules[[2]string{group, id}] = nil
}

func (p *ruleConfigPatch) getGroup(id string) *RuleGroup {
Expand All @@ -110,10 +109,7 @@ func (p *ruleConfigPatch) getGroup(id string) *RuleGroup {
}

func (p *ruleConfigPatch) setGroup(g *RuleGroup) {
old := p.getGroup(g.ID)
if !jsonEquals(old, g) {
p.mut.groups[g.ID] = g
}
p.mut.groups[g.ID] = g
}

func (p *ruleConfigPatch) deleteGroup(id string) {
Expand All @@ -138,6 +134,20 @@ func (p *ruleConfigPatch) adjust() {
p.iterateRules(func(r *Rule) { r.group = p.getGroup(r.GroupID) })
}

// trim unnecessary updates. For example, remove a rule then insert the same rule.
func (p *ruleConfigPatch) trim() {
for key, rule := range p.mut.rules {
if jsonEquals(rule, p.c.getRule(key)) {
delete(p.mut.rules, key)
}
}
for id, group := range p.mut.groups {
if jsonEquals(group, p.c.getGroup(id)) {
delete(p.mut.groups, id)
}
}
}

// merge all mutations to ruleConfig.
func (p *ruleConfigPatch) commit() {
for key, rule := range p.mut.rules {
Expand Down
81 changes: 81 additions & 0 deletions server/schedule/placement/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright 2020 TiKV Project Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package placement

import (
. "github.com/pingcap/check"
)

var _ = Suite(&testConfigSuite{})

type testConfigSuite struct {
}

func (s *testConfigSuite) TestTrim(c *C) {
rc := newRuleConfig()
rc.setRule(&Rule{GroupID: "g1", ID: "id1"})
rc.setRule(&Rule{GroupID: "g1", ID: "id2"})
rc.setRule(&Rule{GroupID: "g2", ID: "id3"})
rc.setGroup(&RuleGroup{ID: "g1", Index: 1})
rc.setGroup(&RuleGroup{ID: "g2", Index: 2})

testCases := []struct {
ops func(p *ruleConfigPatch)
mutRules map[[2]string]*Rule
mutGroups map[string]*RuleGroup
}{
{
func(p *ruleConfigPatch) {
p.setRule(&Rule{GroupID: "g1", ID: "id1", Index: 100})
p.setRule(&Rule{GroupID: "g1", ID: "id2"})
p.setGroup(&RuleGroup{ID: "g1", Index: 100})
p.setGroup(&RuleGroup{ID: "g2", Index: 2})
},
map[[2]string]*Rule{{"g1", "id1"}: {GroupID: "g1", ID: "id1", Index: 100}},
map[string]*RuleGroup{"g1": {ID: "g1", Index: 100}},
},
{
func(p *ruleConfigPatch) {
p.deleteRule("g1", "id1")
p.deleteGroup("g2")
p.deleteRule("g3", "id3")
p.deleteGroup("g3")
},
map[[2]string]*Rule{{"g1", "id1"}: nil},
map[string]*RuleGroup{"g2": {ID: "g2"}},
},
{
func(p *ruleConfigPatch) {
p.setRule(&Rule{GroupID: "g1", ID: "id2", Index: 200})
p.setRule(&Rule{GroupID: "g1", ID: "id2"})
p.setRule(&Rule{GroupID: "g3", ID: "id3"})
p.deleteRule("g3", "id3")
p.setGroup(&RuleGroup{ID: "g1", Index: 100})
p.setGroup(&RuleGroup{ID: "g1", Index: 1})
p.setGroup(&RuleGroup{ID: "g3", Index: 3})
p.deleteGroup("g3")
},
map[[2]string]*Rule{},
map[string]*RuleGroup{},
},
}

for _, tc := range testCases {
p := rc.beginPatch()
tc.ops(p)
p.trim()
c.Assert(p.mut.rules, DeepEquals, tc.mutRules)
c.Assert(p.mut.groups, DeepEquals, tc.mutGroups)
}
}
2 changes: 2 additions & 0 deletions server/schedule/placement/rule_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ func (m *RuleManager) tryCommitPatch(patch *ruleConfigPatch) error {
return err
}

patch.trim()

// save updates
err = m.savePatch(patch.mut)
if err != nil {
Expand Down

0 comments on commit 6322b8e

Please sign in to comment.