@@ -273,7 +273,7 @@ func (r *RegionScatterer) Scatter(region *core.RegionInfo, group string) (*opera
273273
274274func (r * RegionScatterer ) scatterRegion (region * core.RegionInfo , group string ) * operator.Operator {
275275 ordinaryFilter := filter .NewOrdinaryEngineFilter (r .name )
276- ordinaryPeers := make (map [uint64 ]* metapb.Peer )
276+ ordinaryPeers := make (map [uint64 ]* metapb.Peer , len ( region . GetPeers ()) )
277277 specialPeers := make (map [string ]map [uint64 ]* metapb.Peer )
278278 // Group peers by the engine of their stores
279279 for _ , peer := range region .GetPeers () {
@@ -282,24 +282,36 @@ func (r *RegionScatterer) scatterRegion(region *core.RegionInfo, group string) *
282282 return nil
283283 }
284284 if ordinaryFilter .Target (r .cluster .GetOpts (), store ) {
285- ordinaryPeers [peer .GetId ()] = peer
285+ ordinaryPeers [peer .GetStoreId ()] = peer
286286 } else {
287287 engine := store .GetLabelValue (filter .EngineKey )
288288 if _ , ok := specialPeers [engine ]; ! ok {
289289 specialPeers [engine ] = make (map [uint64 ]* metapb.Peer )
290290 }
291- specialPeers [engine ][peer .GetId ()] = peer
291+ specialPeers [engine ][peer .GetStoreId ()] = peer
292292 }
293293 }
294294
295- targetPeers := make (map [uint64 ]* metapb.Peer )
296- selectedStores := make (map [uint64 ]struct {})
297- scatterWithSameEngine := func (peers map [uint64 ]* metapb.Peer , context engineContext ) {
295+ targetPeers := make (map [uint64 ]* metapb.Peer , len ( region . GetPeers ())) // StoreID -> Peer
296+ selectedStores := make (map [uint64 ]struct {}, len ( region . GetPeers ())) // StoreID set
297+ scatterWithSameEngine := func (peers map [uint64 ]* metapb.Peer , context engineContext ) { // peers: StoreID -> Peer
298298 for _ , peer := range peers {
299- candidates := r .selectCandidates (region , peer .GetStoreId (), selectedStores , context )
300- newPeer := r .selectStore (group , peer , peer .GetStoreId (), candidates , context )
301- targetPeers [newPeer .GetStoreId ()] = newPeer
302- selectedStores [newPeer .GetStoreId ()] = struct {}{}
299+ if _ , ok := selectedStores [peer .GetStoreId ()]; ok {
300+ // It is both sourcePeer and targetPeer itself, no need to select.
301+ continue
302+ }
303+ for {
304+ candidates := r .selectCandidates (region , peer .GetStoreId (), selectedStores , context )
305+ newPeer := r .selectStore (group , peer , peer .GetStoreId (), candidates , context )
306+ targetPeers [newPeer .GetStoreId ()] = newPeer
307+ selectedStores [newPeer .GetStoreId ()] = struct {}{}
308+ // If the selected peer is a peer other than origin peer in this region,
309+ // it is considered that the selected peer select itself.
310+ // This origin peer re-selects.
311+ if _ , ok := peers [newPeer .GetStoreId ()]; ! ok || peer .GetStoreId () == newPeer .GetStoreId () {
312+ break
313+ }
314+ }
303315 }
304316 }
305317
0 commit comments