func assignData(blocks []torus.BlockRef, r torus.Ring) ClusterState { out := make(map[string][]torus.BlockRef) for _, p := range r.Members() { out[p] = make([]torus.BlockRef, 0) } for _, b := range blocks { peers, err := r.GetPeers(b) if err != nil { fmt.Fprintf(os.Stderr, "error in the ring: %s\n", err) os.Exit(1) } for _, p := range peers.Peers[:peers.Replication] { out[p] = append(out[p], b) } } return out }
func (c ClusterState) Rebalance(oldRing, newRing torus.Ring) (ClusterState, RebalanceStats) { var stats RebalanceStats out := make(map[string][]torus.BlockRef) for _, p := range newRing.Members() { out[p] = make([]torus.BlockRef, 0) } for p, l := range c { for _, ref := range l { newp, err := newRing.GetPeers(ref) newpeers := newp.Peers[:newp.Replication] if err != nil { fmt.Fprintf(os.Stderr, "error in the new ring: %s\n", err) os.Exit(1) } oldp, err := oldRing.GetPeers(ref) oldpeers := oldp.Peers[:oldp.Replication] if err != nil { fmt.Fprintf(os.Stderr, "error in the old ring: %s\n", err) os.Exit(1) } myIndex := oldpeers.IndexAt(p) if newpeers.Has(p) { out[p] = append(out[p], ref) stats.BlocksKept++ } diffpeers := newpeers.AndNot(oldpeers) if myIndex >= len(diffpeers) { // downsizing continue } if myIndex == len(oldpeers)-1 && len(diffpeers) > len(oldpeers) { for i := myIndex; i < len(diffpeers); i++ { p := diffpeers[i] out[p] = append(out[p], ref) stats.BlocksSent++ } } else { p := diffpeers[myIndex] out[p] = append(out[p], ref) stats.BlocksSent++ } } } return out, stats }