0
点赞
收藏
分享

微信扫一扫

[算法应用]某云SLB负载均衡-中等

​​某云SLB负载均衡​​

描述

假设某云为用户提供服务器时,会将准备好的服务器加入到一个使用池中,用户每次只能使用池中的服务器。为了负载均衡,用户每次要使用的时候会优先挑选最早加入的一台服务器来使用。请实现如下四个函数来实现该负载均衡:add函数,提供服务器ID,系统将该服务器加入到使用池中,假设初始状态使用池中没有服务器。delete函数,提供服务器ID,系统将该ID的服务器从使用池中移除。select函数,每次用户使用服务器时调用,从使用池中选择最早加入的一台未被占据的服务器,返回其ID,没有可使用的服务器时,返回使用池中的服务器数量。release函数,每次用户归还服务器时调用,释放该该用户使用的服务器。输入一个二维数组,其中每个一维数组的第一个元素表示调用的函数,1表示调用add函数,后接一个元素表示ID;2表示调用delete函数,后接一个元素表示ID;3表示调用select函数;4表示调用release函数,后接一个元素表示ID。

示例1

输入:

[[1, 1], [1, 2], [1, 3], [3], [3], [2, 1], [3], [4, 2], [3]]

复制返回值:

[1,2,3,2]

复制说明:

先加入三台服务器到使用池,用户依次使用前两台,删除使用池中的第一台服务器,用户继续使用第三台,归还第二台以后用户使用第二台。

题解

题目很简单,只是描述的不太清楚。和LRU类似,用一个free集合表示可用的机器,用一个use集合表示正在使用中的,用一个hash表存放id和所有集合中元素的映射关系,以便根据id查找。

思路:

1. 定义node节点,存放id和时间戳,id就是题目输入的id,时间戳初始化为1,每次操作的时候自增,当要插入的时候更新node的时间戳

2. 为node定义比较函数,比较准则为时间戳的大小,free_set和use_set都使用该准则,以便取出的第一个元素就是最早加入的机器

3. add操作:判断id是否已经在hash表中,不在就插入到free_set中,并更新hash[id]为插入返回的迭代器

4. delete操作:判断hash[id]是否存在,存在则从free_set或者use_set中删除,然后再从hash中删除

5.select操作:如果free_set为空,返回use_set的个数,否则返回free_set.begin对应的id,并且将该机器移动到use_set中,然后更新hash[id]

6.release操作:将id对于的机器从use_set中删除,然后放入free_set中,并更新hash[id]


代码如下:

struct node
{
int id;
int timestamp;
};

class compare_obj
{
public:
bool operator()(const node &left, const node &right)
{
return left.timestamp < right.timestamp;
}
};
class Solution
{
public:
vector<int> SLB(vector<vector<int>> &operators)
{
int time = 0;
std::set<node, compare_obj> free_set;
std::unordered_map<int, std::set<node>::iterator> hash;
std::set<node, compare_obj> use_set;
std::vector<int> ans;
for (auto &v : operators)
{
int op = v[0];
time++;
if (op == 1) // add
{
if (hash.find(v[1]) == hash.end())
{
node n;
n.id = v[1];
n.timestamp = time;
hash[n.id] = free_set.insert(free_set.begin(), n);
}
}
else if (op == 2) // delete
{
int id = v[1];
if (hash.find(id) != hash.end())
{
if (free_set.find(*hash[id]) != free_set.end())
{
free_set.erase(hash[id]);
}
else if (use_set.find(*hash[id]) != use_set.end())
{
use_set.erase(hash[id]);
}
hash.erase(id);
}
}
else if (op == 3) // select
{
if (free_set.empty())
{
ans.push_back(use_set.size());
}
else
{
auto it = free_set.begin();
ans.push_back(it->id);

hash[it->id] = use_set.insert(use_set.begin(), *it);
free_set.erase(it);
}
}
else if (op == 4) // release
{
int id = v[1];
if (hash.find(id) != hash.end())
{
auto n = *hash[id];
use_set.erase(hash[id]);
hash[id] = free_set.insert(free_set.begin(), n);
}
}
}
return ans;
}
};
举报

相关推荐

0 条评论