mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +00:00
[Instances] Honor reserved instances (#3563)
* [Instances] Honor reserved instances Logic to select next available instance id was incorrect. The correct logic selected the max id + 1 or max reserved + 1, but then it would overwrite if we enabled recycling ids. Additionally, it was incrementing the reserved ids and assigning ids to the max reserved id vice the next available. Finally, it was running the logic twice. * Fix updated SQL to use fmt
This commit is contained in:
parent
a61f951d0e
commit
c47644ea46
@ -131,85 +131,60 @@ bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version
|
|||||||
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||||
{
|
{
|
||||||
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
||||||
uint32 max = 32000;
|
uint32 max_instance_id = 32000;
|
||||||
|
|
||||||
|
// sanity check reserved
|
||||||
|
if (max_reserved_instance_id >= max_instance_id) {
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initial query - get max unused id above reserved
|
||||||
auto query = fmt::format(
|
auto query = fmt::format(
|
||||||
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
|
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
|
||||||
max_reserved_instance_id,
|
max_reserved_instance_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 = (
|
query = fmt::format(
|
||||||
SQL(
|
SQL(
|
||||||
SELECT 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 i2.id = i.id + 1
|
LEFT JOIN instance_list i2 ON i.id + 1 = i2.id
|
||||||
WHERE i2.id IS NULL
|
WHERE i.id > {}
|
||||||
ORDER BY i.id
|
AND i2.id IS NULL;
|
||||||
LIMIT 0, 1;
|
),
|
||||||
|
RuleI(Instances, ReservedInstances)
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
// could not successfully query - bail out
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
instance_id = 0;
|
instance_id = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no instances running - assign first id above reserved
|
||||||
if (results.RowCount() == 0) {
|
if (results.RowCount() == 0) {
|
||||||
instance_id = max_reserved_instance_id;
|
instance_id = max_reserved_instance_id + 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
if (Strings::ToInt(row[0]) <= max) {
|
// check that id is within limits
|
||||||
|
if (Strings::ToInt(row[0]) <= max_instance_id) {
|
||||||
instance_id = Strings::ToInt(row[0]);
|
instance_id = Strings::ToInt(row[0]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance_id < max_reserved_instance_id) {
|
// unhandled situation - should not reach here
|
||||||
instance_id = max_reserved_instance_id;
|
instance_id = 0;
|
||||||
return true;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format("SELECT id FROM instance_list where id > {} ORDER BY id", max_reserved_instance_id);
|
|
||||||
results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success()) {
|
|
||||||
instance_id = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.RowCount() == 0) {
|
|
||||||
instance_id = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_reserved_instance_id++;
|
|
||||||
|
|
||||||
for (auto row : results) {
|
|
||||||
if (max_reserved_instance_id < Strings::ToUnsignedInt(row[0])) {
|
|
||||||
instance_id = max_reserved_instance_id;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max_reserved_instance_id > max) {
|
|
||||||
instance_id = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_reserved_instance_id++;
|
|
||||||
}
|
|
||||||
|
|
||||||
instance_id = max_reserved_instance_id;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::IsGlobalInstance(uint16 instance_id)
|
bool Database::IsGlobalInstance(uint16 instance_id)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user