github.com/m3db/m3@v1.5.0/src/cluster/placement/algo/non_sharded.go (about) 1 // Copyright (c) 2016 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package algo 22 23 import ( 24 "errors" 25 "fmt" 26 27 "github.com/m3db/m3/src/cluster/placement" 28 ) 29 30 var ( 31 errShardsOnNonShardedAlgo = errors.New("could not apply shards in non-sharded placement") 32 errInCompatibleWithNonShardedAlgo = errors.New("could not apply non-sharded algo on the placement") 33 ) 34 35 type nonShardedAlgorithm struct{} 36 37 func newNonShardedAlgorithm() placement.Algorithm { 38 return nonShardedAlgorithm{} 39 } 40 41 func (a nonShardedAlgorithm) IsCompatibleWith(p placement.Placement) error { 42 if p.IsSharded() { 43 return errInCompatibleWithNonShardedAlgo 44 } 45 46 if p.IsMirrored() { 47 return errInCompatibleWithNonShardedAlgo 48 } 49 50 return nil 51 } 52 53 func (a nonShardedAlgorithm) InitialPlacement( 54 instances []placement.Instance, 55 shards []uint32, 56 rf int, 57 ) (placement.Placement, error) { 58 if len(shards) > 0 { 59 return nil, errShardsOnNonShardedAlgo 60 } 61 62 return placement.NewPlacement(). 63 SetInstances(placement.Instances(instances).Clone()). 64 SetShards(shards). 65 SetReplicaFactor(rf). 66 SetIsSharded(false), nil 67 } 68 69 func (a nonShardedAlgorithm) AddReplica(p placement.Placement) (placement.Placement, error) { 70 if err := a.IsCompatibleWith(p); err != nil { 71 return nil, err 72 } 73 74 return p.Clone().SetReplicaFactor(p.ReplicaFactor() + 1), nil 75 } 76 77 func (a nonShardedAlgorithm) RemoveInstances( 78 p placement.Placement, 79 instanceIDs []string, 80 ) (placement.Placement, error) { 81 if err := a.IsCompatibleWith(p); err != nil { 82 return nil, err 83 } 84 85 removingInstances := make([]placement.Instance, len(instanceIDs)) 86 for i, id := range instanceIDs { 87 instance, ok := p.Instance(id) 88 if !ok { 89 return nil, fmt.Errorf("instance %s not found in placement", id) 90 } 91 removingInstances[i] = instance 92 } 93 94 p = p.Clone() 95 instances := p.Instances() 96 for _, instance := range removingInstances { 97 instances = removeInstanceFromList(instances, instance.ID()) 98 } 99 return p.SetInstances(instances), nil 100 } 101 102 func (a nonShardedAlgorithm) AddInstances( 103 p placement.Placement, 104 addingInstances []placement.Instance, 105 ) (placement.Placement, error) { 106 if err := a.IsCompatibleWith(p); err != nil { 107 return nil, err 108 } 109 110 p = p.Clone() 111 instances := p.Instances() 112 for _, instance := range addingInstances { 113 if _, ok := p.Instance(instance.ID()); ok { 114 return nil, fmt.Errorf("instance %s already exist in placement", instance.ID()) 115 } 116 instances = append(instances, instance) 117 } 118 119 return p.SetInstances(instances), nil 120 } 121 122 func (a nonShardedAlgorithm) ReplaceInstances( 123 p placement.Placement, 124 leavingInstanceIDs []string, 125 addingInstances []placement.Instance, 126 ) (placement.Placement, error) { 127 if err := a.IsCompatibleWith(p); err != nil { 128 return nil, err 129 } 130 131 p, err := a.AddInstances(p, addingInstances) 132 if err != nil { 133 return nil, err 134 } 135 136 return a.RemoveInstances(p, leavingInstanceIDs) 137 } 138 139 func (a nonShardedAlgorithm) MarkShardsAvailable( 140 p placement.Placement, 141 instanceID string, 142 shardIDs ...uint32, 143 ) (placement.Placement, error) { 144 if err := a.IsCompatibleWith(p); err != nil { 145 return nil, err 146 } 147 // There is no shards in non-sharded algorithm. 148 return p, nil 149 } 150 151 func (a nonShardedAlgorithm) MarkAllShardsAvailable( 152 p placement.Placement, 153 ) (placement.Placement, bool, error) { 154 if err := a.IsCompatibleWith(p); err != nil { 155 return nil, false, err 156 } 157 // There is no shards in non-sharded algorithm. 158 return p, false, nil 159 } 160 161 func (a nonShardedAlgorithm) BalanceShards( 162 p placement.Placement, 163 ) (placement.Placement, error) { 164 if err := a.IsCompatibleWith(p); err != nil { 165 return nil, err 166 } 167 // There is no shards in non-sharded algorithm. 168 return p, nil 169 }