mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 18:51:29 +00:00
[Instances] Refine id selection (#3568)
* [Instances] Refine id selection Since the IDs start above the minimum, we needed to check if the first slot was available. * Remove else by returning early, add validation before accessing row --------- Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
parent
a2b78ff4e6
commit
37dda9bf41
@ -139,27 +139,79 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// initial query - get max unused id above reserved
|
// recycle instances
|
||||||
auto query = fmt::format(
|
|
||||||
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
|
|
||||||
max_reserved_instance_id,
|
|
||||||
max_reserved_instance_id
|
|
||||||
);
|
|
||||||
|
|
||||||
// recycle instances - change query to get first unused id above reserved
|
|
||||||
if (RuleB(Instances, RecycleInstanceIds)) {
|
if (RuleB(Instances, RecycleInstanceIds)) {
|
||||||
|
|
||||||
|
//query to get first unused id above reserved
|
||||||
|
auto query = fmt::format(
|
||||||
|
SQL(
|
||||||
|
SELECT id
|
||||||
|
FROM instance_list
|
||||||
|
WHERE id = {};
|
||||||
|
),
|
||||||
|
max_reserved_instance_id + 1
|
||||||
|
);
|
||||||
|
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
// could not successfully query - bail out
|
||||||
|
if (!results.Success()) {
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first id is available
|
||||||
|
if (results.RowCount() == 0) {
|
||||||
|
instance_id = max_reserved_instance_id + 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now look for next available above reserved
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
SQL(
|
SQL(
|
||||||
SELECT MIN(i.id + 1) AS next_available
|
SELECT MIN(i.id + 1) AS next_available
|
||||||
FROM instance_list i
|
FROM instance_list i
|
||||||
LEFT JOIN instance_list i2 ON i.id + 1 = i2.id
|
LEFT JOIN instance_list i2 ON i.id + 1 = i2.id
|
||||||
WHERE i.id > {}
|
WHERE i.id >= {}
|
||||||
AND i2.id IS NULL;
|
AND i2.id IS NULL;
|
||||||
),
|
),
|
||||||
RuleI(Instances, ReservedInstances)
|
max_reserved_instance_id
|
||||||
);
|
);
|
||||||
|
|
||||||
|
results = QueryDatabase(query);
|
||||||
|
|
||||||
|
// could not successfully query - bail out
|
||||||
|
if (!results.Success()) {
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// did not retrieve any rows - bail out
|
||||||
|
if (results.RowCount() == 0) {
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
// check that id is within limits
|
||||||
|
if (row[0] && Strings::ToInt(row[0]) <= max_instance_id) {
|
||||||
|
instance_id = Strings::ToInt(row[0]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no available instance ids
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get max unused id above reserved
|
||||||
|
auto query = fmt::format(
|
||||||
|
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
|
||||||
|
max_reserved_instance_id,
|
||||||
|
max_reserved_instance_id
|
||||||
|
);
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
// could not successfully query - bail out
|
// could not successfully query - bail out
|
||||||
@ -168,21 +220,27 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// no instances running - assign first id above reserved
|
// did not retrieve any rows - bail out
|
||||||
if (results.RowCount() == 0) {
|
if (results.RowCount() == 0) {
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
// no instances currently used
|
||||||
|
if (!row[0]) {
|
||||||
instance_id = max_reserved_instance_id + 1;
|
instance_id = max_reserved_instance_id + 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto row : results) {
|
// check that id is within limits
|
||||||
// check that id is within limits
|
if (Strings::ToInt(row[0]) <= max_instance_id) {
|
||||||
if (row[0] && Strings::ToInt(row[0]) <= max_instance_id) {
|
instance_id = Strings::ToInt(row[0]);
|
||||||
instance_id = Strings::ToInt(row[0]);
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unhandled situation - should not reach here
|
// no available instance ids
|
||||||
instance_id = 0;
|
instance_id = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user