|
@@ -4139,56 +4139,54 @@ StationID FlowStat::GetVia(StationID exc
|
|
|
}
|
|
|
rand = RandomRange(new_max);
|
|
|
SharesMap::const_iterator it3 = this->shares.upper_bound(this->unrestricted);
|
|
|
if (rand < begin) {
|
|
|
it3 = this->shares.upper_bound(rand);
|
|
|
} else if (rand < begin2 - interval) {
|
|
|
it3 = this->shares.upper_bound(rand + interval);
|
|
|
} else {
|
|
|
it3 = this->shares.upper_bound(rand + interval + interval2);
|
|
|
}
|
|
|
assert(it3 != this->shares.end() && it3->first <= this->unrestricted);
|
|
|
return it3->second;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Reduce all flows to minimum capacity so that they don't get in the way of
|
|
|
* link usage statistics too much. Keep them around, though, to continue
|
|
|
* routing any remaining cargo.
|
|
|
*/
|
|
|
void FlowStat::Invalidate()
|
|
|
{
|
|
|
assert(!this->shares.empty());
|
|
|
SharesMap new_shares;
|
|
|
uint i = 0;
|
|
|
uint orig = 0;
|
|
|
for (SharesMap::iterator it(this->shares.begin()); it != this->shares.end(); ++it) {
|
|
|
new_shares[++i] = it->second;
|
|
|
orig += it->first;
|
|
|
if (orig == this->unrestricted) this->unrestricted = orig;
|
|
|
if (it->first == this->unrestricted) this->unrestricted = i;
|
|
|
}
|
|
|
this->shares.swap(new_shares);
|
|
|
assert(!this->shares.empty());
|
|
|
assert(!this->shares.empty() && this->unrestricted <= (--this->shares.end())->first);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Change share for specified station. By specifing INT_MIN as parameter you
|
|
|
* can erase a share. Newly added flows will be unrestricted.
|
|
|
* @param st Next Hop to be removed.
|
|
|
* @param flow Share to be added or removed.
|
|
|
*/
|
|
|
void FlowStat::ChangeShare(StationID st, int flow)
|
|
|
{
|
|
|
/* We assert only before changing as afterwards the shares can actually
|
|
|
* be empty. In that case the whole flow stat must be deleted then. */
|
|
|
assert(!this->shares.empty());
|
|
|
|
|
|
uint removed_shares = 0;
|
|
|
uint added_shares = 0;
|
|
|
uint last_share = 0;
|
|
|
SharesMap new_shares;
|
|
|
for (SharesMap::iterator it(this->shares.begin()); it != this->shares.end(); ++it) {
|
|
|
if (it->second == st) {
|
|
|
if (flow < 0) {
|
|
|
uint share = it->first - last_share;
|
|
|
if (flow == INT_MIN || (uint)(-flow) >= share) {
|
|
|
removed_shares += share;
|