/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.dubbo.rpc.cluster.loadbalance;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * This class select one provider from multiple providers randomly.
 * You can define weights for each provider:
 * If the weights are all the same then it will use random.nextInt(number of invokers).
 * If the weights are different then it will use random.nextInt(w1 + w2 + ... + wn)
 * Note that if the performance of the machine is better than others, you can set a larger weight.
 * If the performance is not so good, you can set a smaller weight.
 */
public class RandomLoadBalance extends AbstractLoadBalance {

    public static final String NAME = "random";

    /**
     * Select one invoker between a list using a random criteria
     * @param invokers List of possible invokers
     * @param url URL
     * @param invocation Invocation
     * @param <T>
     * @return The selected invoker
     */
    @Override
    protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        // Number of invokers
        int length = invokers.size();
        // Every invoker has the same weight?
        boolean sameWeight = true;
        // the weight of every invokers
        int[] weights = new int[length];
        // the first invoker's weight
        int firstWeight = getWeight(invokers.get(0), invocation);
        weights[0] = firstWeight;
        // The sum of weights
        int totalWeight = firstWeight;
        for (int i = 1; i < length; i++) {
            int weight = getWeight(invokers.get(i), invocation);
            // save for later use
            weights[i] = weight;
            // Sum
            totalWeight += weight;
            if (sameWeight && weight != firstWeight) {
                sameWeight = false;
            }
        }
        if (totalWeight > 0 && !sameWeight) {
            // If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on totalWeight.
            int offset = ThreadLocalRandom.current().nextInt(totalWeight);
            // Return a invoker based on the random value.
            for (int i = 0; i < length; i++) {
                offset -= weights[i];
                if (offset < 0) {
                    return invokers.get(i);
                }
            }
        }
        // If all invokers have the same weight value or totalWeight=0, return evenly.
        return invokers.get(ThreadLocalRandom.current().nextInt(length));
    }

}

@@ -2117,25 +2117,28 @@
      // the 
-w
+maxW
 eight of eve
@@ -2152,68 +2152,54 @@
 kers
-%0A        int%5B%5D w
+, the minW
 eight
-s
  = 
-new int%5Blength%5D;%0A        //
+0 or the maxWeight of
  the 
-fir
+la
 st i
@@ -2204,25 +2204,16 @@
  invoker
-'s weight
 %0A       
@@ -2220,95 +2220,36 @@
  int
- firstW
+%5B%5D w
 eight
+s
  = 
-getWeight(invokers.get(0), invocation);%0A        weights%5B0%5D = firstWeight
+new int%5Blength%5D
 ;%0A  
@@ -2302,27 +2302,17 @@
 eight = 
-firstWeight
+0
 ;%0A      
@@ -2326,17 +2326,17 @@
 int i = 
-1
+0
 ; i %3C le
@@ -2432,107 +2432,112 @@
  // 
-save for later use%0A            weights%5Bi%5D = weight;%0A            // Sum%0A            totalWeight += w
+Sum%0A            totalWeight += weight;%0A            // save for later use%0A            weights%5Bi%5D = totalW
 eigh
@@ -2569,17 +2569,22 @@
 ight && 
-w
+totalW
 eight !=
@@ -2588,19 +2588,24 @@
  != 
-firstWeight
+weight * (i + 1)
 ) %7B%0A
@@ -3042,17 +3042,20 @@
     
+if (
 offset 
--=
+%3C
  wei
@@ -3065,40 +3065,8 @@
 s%5Bi%5D
-;%0A                if (offset %3C 0
 ) %7B%0A

update that how to judge the same weight (#6479)