Load Balancer 526

Question

Implement a load balancer for web servers. It provide the following functionality:

Add a new server to the cluster => add(server_id).

Remove a bad server from the cluster => remove(server_id).

Pick a server in the cluster randomly with equal probability => pick().

Example

At beginning, the cluster is empty => {}.

add(1)
add(2)
add(3)
pick()
>> 1         // the return value is random, it can be either 1, 2, or 3.
pick()
>> 2
pick()
>> 1
pick()
>> 3
remove(1)
pick()
>> 2
pick()
>> 3
pick()
>> 3

Solution

add(): 用list保存加入的server,用dict记录每个server加入的位置,重复加入的server会更新为最新的位置。

remove(): 先从dict中得到要删去server的位置,然后将list中最后一位元素移到该位置上,并将dict中该元素的位置更新,最后删去最后一位元素,并将dict中要删去的server删去。为什么要移动而不能直接删去?增加随机性?

pick(): 用random对象随机生成,nextInt()取整之后%list.size()得到0-list.size()之间的随机数。

代码如下:

public class LoadBalancer {
    ArrayList<Integer> list;
    HashMap<Integer, Integer> dict;

    public LoadBalancer() {
        // Initialize your data structure here.
        list = new ArrayList<Integer>();
        dict = new HashMap<Integer, Integer>();
    }

    // @param server_id add a new server to the cluster 
    // @return void
    public void add(int server_id) {
        // Write your code here
        int index = list.size();
        //用dict记录每个server加入的位置,重复加入的server会更新为最新的位置
        dict.put(server_id, index);
        list.add(server_id);
    }

    // @param server_id server_id remove a bad server from the cluster
    // @return void
    public void remove(int server_id) {
        // Write your code here
        //获得要删除元素的位置
        int index = dict.get(server_id);
        //若要删除的server不存在则返回
        if(index == -1){
            return;
        }
        int n = list.size();
        //将list最后一个server移到要删除的位置上,并更新该元素在dict中记录的位置
        list.set(index, list.get(n - 1));
        dict.put(list.get(n - 1), index);
        //删去最后一个元素
        list.remove(n - 1);
        dict.remove(server_id);
    }

    // @return pick a server in the cluster randomly with equal probability
    public int pick() {
        // Write your code here
        int size = list.size();
        Random r = new Random();
        int index = Math.abs(r.nextInt()) % size;
        return list.get(index);
    } 
}

results matching ""

    No results matching ""