我正在处理一个需求,要求请求的编号在 -2 到 -101 之间是唯一的,即每次有100个独特的请求。如果在给定时间内有超过100个请求,则应返回错误。最初,我没有任何请求。一旦发送请求,我将获得独特的号码,比如 -2,-3 等等。这里的要求是,我可能会收到客户端的命令,要求不要向服务器发送例如 -2 的请求,因此我应该删除这个请求,并且我应该重用这个编号以供将来的请求使用。
最好的实现方式是什么?此外,我不应该使用 Boost。
最好的实现方式是什么?此外,我不应该使用 Boost。
关于我的std::bitset
评论的进一步解释:
您可以使用id作为位集的索引,而值(true/false
)表示id的可用性。
class IdStorage {
const int N = 100;
std::bitset<N> ids;
bool allIdsUsed() {
return ids.all();
}
int getId() {
if(allIdsUsed())
throw "Error";
for(int i = 0; i < N; ++i )
if(ids.test(i))
return i - 2;
}
void releaseId(int i) {
ids.set(i + 2);
}
}
您需要至少维护一个未使用的id集合。此外,我建议添加一个查找表来验证是否分配了id(以提高健壮性)。对于这两个功能,我建议使用std::vector
而不是列表。
首先,在std::vector<int>
中存储未使用的集合,您可以非常轻松地初始化:
class IdStore {
private:
std::vector<int> unused;
static int const MIN_ID = -101;
static int const MAX_ID = -2;
public:
IdStore::IdStore()
: unused(MAX_ID - MIN_ID + 1) {
for (auto i = 0; i <= MAX_ID-MIN_ID; ++i) {
unused[i] = i;
}
}
int getId();
void releaseId(int);
};
std :: vector <bool> used;
成员来实现,您可以通过used(MAX_ID - MIN_ID +1)
简单地初始化它,因为它的值最初都将默认为false
。当然,您也可以将used
作为bitset
,但请注意,这需要在编译时知道从MIN_ID
到MAX_ID
的距离。int IdStore::getId() {
if (unused.empty())
throw "error"; // put something better here
auto r = unused.back();
used[r] = true;
unused.pop_back();
return MIN_ID + r;
}
void IdStore::releaseId(int id) {
if (id < MIN_ID || id > MAX_ID)
throw "error"; // put something better here
id -= MIN_ID;
if (!used[id])
throw "error"; // put something better here
used[id] = false;
unused.push_back(id);
}
getId
和releaseId
都不需要昂贵的malloc
或free
调用。请参考此处。std::vector<bool>
的特化,但我认为在这种情况下应该没问题。 - bitmaskstd::bitset
是最好的选择。 - TeaOverflow对于仅有的100个数字,可能没有显著的性能差异,您可以使用集合或数组;普通老式数组,例如id_used [100]
在性能测试中可能会胜出。
如果您需要可扩展的解决方案,请尝试使用“自由集”和“已使用集”,其中自由集存储空闲可用的ID,已使用集存储已经在使用中的ID。使用ID后,请将其存回到自由集中。
对于允许ID与并发使用比之间足够大的情况,请仅使用“已使用集”,并使用拒绝采样找到空闲的ID:
do {
id = generate_id();
} while(std::end != used_set.find(id));
无论如何,没有明确的答案。
我还没有编译它,但应该是这样的:
std::list<int> list;
for(int i=start; i<=end; ++i)
list.insert(i);
//when get Id request
Id2send = list.first();
list.remove(list.first());
//when delete id request
list.remove(id);
//when add id request (this happens when an id is freed or other times)
list.add(id);
std::map
这样的?或者只是一个数组bool id_used[100]
,如果使用了一个ID就将其设置为true
? - Some programmer dude