Tracerestrict: Use btree_multimap for slot vehicle index

This commit is contained in:
Jonathan G Rennison
2023-03-06 23:51:17 +00:00
parent 633c72b10b
commit 70311c0843
2 changed files with 21 additions and 21 deletions

View File

@@ -24,6 +24,7 @@
#include "scope_info.h" #include "scope_info.h"
#include "vehicle_func.h" #include "vehicle_func.h"
#include "date_func.h" #include "date_func.h"
#include "3rdparty/cpp-btree/btree_map.h"
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
@@ -2138,7 +2139,7 @@ void TraceRestrictUpdateCompanyID(CompanyID old_company, CompanyID new_company)
InvalidateWindowClassesData(WC_TRACE_RESTRICT_COUNTERS); InvalidateWindowClassesData(WC_TRACE_RESTRICT_COUNTERS);
} }
static std::unordered_multimap<VehicleID, TraceRestrictSlotID> slot_vehicle_index; static btree::btree_multimap<VehicleID, TraceRestrictSlotID> slot_vehicle_index;
/** /**
* Add vehicle ID to occupants if possible and not already an occupant * Add vehicle ID to occupants if possible and not already an occupant
@@ -2151,7 +2152,7 @@ bool TraceRestrictSlot::Occupy(VehicleID id, bool force)
if (this->IsOccupant(id)) return true; if (this->IsOccupant(id)) return true;
if (this->occupants.size() >= this->max_occupancy && !force) return false; if (this->occupants.size() >= this->max_occupancy && !force) return false;
this->occupants.push_back(id); this->occupants.push_back(id);
slot_vehicle_index.emplace(id, this->index); slot_vehicle_index.insert({ id, this->index });
SetBit(Vehicle::Get(id)->vehicle_flags, VF_HAVE_SLOT); SetBit(Vehicle::Get(id)->vehicle_flags, VF_HAVE_SLOT);
SetWindowDirty(WC_VEHICLE_DETAILS, id); SetWindowDirty(WC_VEHICLE_DETAILS, id);
InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS); InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
@@ -2233,14 +2234,14 @@ void TraceRestrictSlot::UpdateSignals() {
void TraceRestrictSlot::DeIndex(VehicleID id) void TraceRestrictSlot::DeIndex(VehicleID id)
{ {
auto range = slot_vehicle_index.equal_range(id); auto start = slot_vehicle_index.lower_bound(id);
for (auto it = range.first; it != range.second; ++it) { for (auto it = start; it != slot_vehicle_index.end() && it->first == id; ++it) {
if (it->second == this->index) { if (it->second == this->index) {
bool is_first_in_range = (it == range.first); bool is_first_in_range = (it == start);
auto next = slot_vehicle_index.erase(it); auto next = slot_vehicle_index.erase(it);
if (is_first_in_range && next == range.second) { if (is_first_in_range && (next == slot_vehicle_index.end() || next->first != id)) {
/* Only one item, which we've just erased, clear the vehicle flag */ /* Only one item, which we've just erased, clear the vehicle flag */
ClrBit(Vehicle::Get(id)->vehicle_flags, VF_HAVE_SLOT); ClrBit(Vehicle::Get(id)->vehicle_flags, VF_HAVE_SLOT);
} }
@@ -2257,16 +2258,16 @@ void TraceRestrictSlot::RebuildVehicleIndex()
slot_vehicle_index.clear(); slot_vehicle_index.clear();
for (const TraceRestrictSlot *slot : TraceRestrictSlot::Iterate()) { for (const TraceRestrictSlot *slot : TraceRestrictSlot::Iterate()) {
for (VehicleID id : slot->occupants) { for (VehicleID id : slot->occupants) {
slot_vehicle_index.emplace(id, slot->index); slot_vehicle_index.insert({ id, slot->index });
} }
} }
} }
bool TraceRestrictSlot::ValidateVehicleIndex() bool TraceRestrictSlot::ValidateVehicleIndex()
{ {
std::unordered_multimap<VehicleID, TraceRestrictSlotID> saved_slot_vehicle_index = std::move(slot_vehicle_index); btree::btree_multimap<VehicleID, TraceRestrictSlotID> saved_slot_vehicle_index = std::move(slot_vehicle_index);
RebuildVehicleIndex(); RebuildVehicleIndex();
const bool ok = slot_vehicle_index == saved_slot_vehicle_index; bool ok = multimaps_equalivalent(saved_slot_vehicle_index, slot_vehicle_index);
slot_vehicle_index = std::move(saved_slot_vehicle_index); slot_vehicle_index = std::move(saved_slot_vehicle_index);
return ok; return ok;
} }
@@ -2319,17 +2320,17 @@ void TraceRestrictSlot::RevertTemporaryChanges(VehicleID veh)
/** Remove vehicle ID from all slot occupants */ /** Remove vehicle ID from all slot occupants */
void TraceRestrictRemoveVehicleFromAllSlots(VehicleID vehicle_id) void TraceRestrictRemoveVehicleFromAllSlots(VehicleID vehicle_id)
{ {
const auto range = slot_vehicle_index.equal_range(vehicle_id); const auto start = slot_vehicle_index.lower_bound(vehicle_id);
auto it = start;
for (auto it = range.first; it != range.second; ++it) { for (; it != slot_vehicle_index.end() && it->first == vehicle_id; ++it) {
auto slot = TraceRestrictSlot::Get(it->second); auto slot = TraceRestrictSlot::Get(it->second);
container_unordered_remove(slot->occupants, vehicle_id); container_unordered_remove(slot->occupants, vehicle_id);
slot->UpdateSignals(); slot->UpdateSignals();
} }
const bool anything_to_erase = range.first != range.second; const bool anything_to_erase = (start != it);
slot_vehicle_index.erase(range.first, range.second); slot_vehicle_index.erase(start, it);
if (anything_to_erase) InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS); if (anything_to_erase) InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS);
} }
@@ -2337,18 +2338,19 @@ void TraceRestrictRemoveVehicleFromAllSlots(VehicleID vehicle_id)
/** Replace all instance of a vehicle ID with another, in all slot occupants */ /** Replace all instance of a vehicle ID with another, in all slot occupants */
void TraceRestrictTransferVehicleOccupantInAllSlots(VehicleID from, VehicleID to) void TraceRestrictTransferVehicleOccupantInAllSlots(VehicleID from, VehicleID to)
{ {
auto range = slot_vehicle_index.equal_range(from);
std::vector<TraceRestrictSlotID> slots; std::vector<TraceRestrictSlotID> slots;
for (auto it = range.first; it != range.second; ++it) { const auto start = slot_vehicle_index.lower_bound(from);
auto it = start;
for (; it != slot_vehicle_index.end() && it->first == from; ++it) {
slots.push_back(it->second); slots.push_back(it->second);
} }
slot_vehicle_index.erase(range.first, range.second); slot_vehicle_index.erase(start, it);
for (TraceRestrictSlotID slot_id : slots) { for (TraceRestrictSlotID slot_id : slots) {
TraceRestrictSlot *slot = TraceRestrictSlot::Get(slot_id); TraceRestrictSlot *slot = TraceRestrictSlot::Get(slot_id);
for (VehicleID &id : slot->occupants) { for (VehicleID &id : slot->occupants) {
if (id == from) { if (id == from) {
id = to; id = to;
slot_vehicle_index.emplace(to, slot_id); slot_vehicle_index.insert({ to, slot_id });
} }
} }
} }
@@ -2358,8 +2360,7 @@ void TraceRestrictTransferVehicleOccupantInAllSlots(VehicleID from, VehicleID to
/** Get list of slots occupied by a vehicle ID */ /** Get list of slots occupied by a vehicle ID */
void TraceRestrictGetVehicleSlots(VehicleID id, std::vector<TraceRestrictSlotID> &out) void TraceRestrictGetVehicleSlots(VehicleID id, std::vector<TraceRestrictSlotID> &out)
{ {
auto range = slot_vehicle_index.equal_range(id); for (auto it = slot_vehicle_index.lower_bound(id); it != slot_vehicle_index.end() && it->first == id; ++it) {
for (auto it = range.first; it != range.second; ++it) {
out.push_back(it->second); out.push_back(it->second);
} }
} }

View File

@@ -24,7 +24,6 @@
#include "3rdparty/cpp-btree/btree_map.h" #include "3rdparty/cpp-btree/btree_map.h"
#include <map> #include <map>
#include <vector> #include <vector>
#include <unordered_map>
struct Train; struct Train;