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