[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:
JJ 2023-08-28 20:28:15 -04:00 committed by GitHub
parent a2b78ff4e6
commit 37dda9bf41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -139,27 +139,79 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
return false;
}
// initial query - 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
);
// recycle instances - change query to get first unused id above reserved
// recycle instances
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(
SQL(
SELECT MIN(i.id + 1) AS next_available
FROM instance_list i
LEFT JOIN instance_list i2 ON i.id + 1 = i2.id
WHERE i.id > {}
WHERE i.id >= {}
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);
// could not successfully query - bail out
@ -168,21 +220,27 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
return false;
}
// no instances running - assign first id above reserved
// did not retrieve any rows - bail out
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;
return true;
}
for (auto row : results) {
// check that id is within limits
if (row[0] && Strings::ToInt(row[0]) <= max_instance_id) {
instance_id = Strings::ToInt(row[0]);
return true;
}
// check that id is within limits
if (Strings::ToInt(row[0]) <= max_instance_id) {
instance_id = Strings::ToInt(row[0]);
return true;
}
// unhandled situation - should not reach here
// no available instance ids
instance_id = 0;
return false;
}