I am working on a requirement where requests should have unique number from -2 to -101 inclusive, i.e., there are unique 100 requests at a time. If there are more than 100 requests at a given time then I should send error. Initially I have no requests. Once I sent requests I will take unique number say -2 , -3 and so on. Here requirement is that I may get command from client don't sent request to server for example -2 so I should delete this request and I should reuse this number for future request.
What is the best way to implement this in C++?
Also, I am not supposed to use Boost.
Expanding on my std::bitset comment:
You can use the id as the index of the bitset and the value (true/false) as the availability of the 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);
}
}
Note that typed this in class, out of my head. Check the documentation
You have to maintain a collection of unused ids at least. Additionally I would throw in a lookup table to verify that an id was handed out (for robustness). For both, I would suggest to use an std::vector, not a list.
First, store the unused collection in an std::vector<int>, which you can very easily initialise:
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);
};
Additionally, you may want to keep track of the used ids, so you can verify if they were handed out; I'd use an std::vector<bool> used; member for that, which you can initialise simply with used(MAX_ID - MIN_ID +1) as its values will all default to false initially. Of course, you can make used also a bitset but note that this would require the distance from MIN_ID to MAX_ID to be known at compile time.
Handing out stuff is pretty simple from there:
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;
}
And releasing them, also:
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);
}
Note that no reallocations take place! The vector will keep its size and neither getId nor releaseId will require expensive calls to malloc or free contrary to an approach using a list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With