* Change share for specified station. By specifying 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. */
| 5075 | * @param flow Share to be added or removed. |
| 5076 | */ |
| 5077 | void FlowStat::ChangeShare(StationID st, int flow) |
| 5078 | { |
| 5079 | /* We assert only before changing as afterwards the shares can actually |
| 5080 | * be empty. In that case the whole flow stat must be deleted then. */ |
| 5081 | assert(!this->shares.empty()); |
| 5082 | |
| 5083 | uint removed_shares = 0; |
| 5084 | uint added_shares = 0; |
| 5085 | uint last_share = 0; |
| 5086 | SharesMap new_shares; |
| 5087 | for (const auto &it : this->shares) { |
| 5088 | if (it.second == st) { |
| 5089 | if (flow < 0) { |
| 5090 | uint share = it.first - last_share; |
| 5091 | if (flow == INT_MIN || (uint)(-flow) >= share) { |
| 5092 | removed_shares += share; |
| 5093 | if (it.first <= this->unrestricted) this->unrestricted -= share; |
| 5094 | if (flow != INT_MIN) flow += share; |
| 5095 | last_share = it.first; |
| 5096 | continue; // remove the whole share |
| 5097 | } |
| 5098 | removed_shares += (uint)(-flow); |
| 5099 | } else { |
| 5100 | added_shares += (uint)(flow); |
| 5101 | } |
| 5102 | if (it.first <= this->unrestricted) this->unrestricted += flow; |
| 5103 | |
| 5104 | /* If we don't continue above the whole flow has been added or |
| 5105 | * removed. */ |
| 5106 | flow = 0; |
| 5107 | } |
| 5108 | new_shares[it.first + added_shares - removed_shares] = it.second; |
| 5109 | last_share = it.first; |
| 5110 | } |
| 5111 | if (flow > 0) { |
| 5112 | new_shares[last_share + (uint)flow] = st; |
| 5113 | if (this->unrestricted < last_share) { |
| 5114 | this->ReleaseShare(st); |
| 5115 | } else { |
| 5116 | this->unrestricted += flow; |
| 5117 | } |
| 5118 | } |
| 5119 | this->shares.swap(new_shares); |
| 5120 | } |
| 5121 | |
| 5122 | /** |
| 5123 | * Restrict a flow by moving it to the end of the map and decreasing the amount |
no test coverage detected