* Estimate the amounts of cargo per final destination for a given cargo, source station and next hop and * save the result as children of the given CargoDataEntry. * @param cargo type of the cargo to estimate destinations for. * @param source Source station of the given batch of cargo. * @param next Intermediate hop to start the calculation at ("next hop"). * @param count Size of the bat
| 1525 | * @param dest CargoDataEntry to save the results in. |
| 1526 | */ |
| 1527 | void EstimateDestinations(CargoType cargo, StationID source, StationID next, uint count, CargoDataEntry &dest) |
| 1528 | { |
| 1529 | if (Station::IsValidID(next) && Station::IsValidID(source)) { |
| 1530 | GoodsEntry &ge = Station::Get(next)->goods[cargo]; |
| 1531 | if (!ge.HasData()) return; |
| 1532 | |
| 1533 | CargoDataEntry tmp; |
| 1534 | const FlowStatMap &flowmap = ge.GetData().flows; |
| 1535 | FlowStatMap::const_iterator map_it = flowmap.find(source); |
| 1536 | if (map_it != flowmap.end()) { |
| 1537 | const FlowStat::SharesMap *shares = map_it->second.GetShares(); |
| 1538 | uint32_t prev_count = 0; |
| 1539 | for (FlowStat::SharesMap::const_iterator i = shares->begin(); i != shares->end(); ++i) { |
| 1540 | tmp.InsertOrRetrieve(i->second).Update(i->first - prev_count); |
| 1541 | prev_count = i->first; |
| 1542 | } |
| 1543 | } |
| 1544 | |
| 1545 | if (tmp.GetCount() == 0) { |
| 1546 | dest.InsertOrRetrieve(StationID::Invalid()).Update(count); |
| 1547 | } else { |
| 1548 | uint sum_estimated = 0; |
| 1549 | while (sum_estimated < count) { |
| 1550 | for (CargoDataSet::iterator i = tmp.Begin(); i != tmp.End() && sum_estimated < count; ++i) { |
| 1551 | CargoDataEntry &child = **i; |
| 1552 | uint estimate = DivideApprox(child.GetCount() * count, tmp.GetCount()); |
| 1553 | if (estimate == 0) estimate = 1; |
| 1554 | |
| 1555 | sum_estimated += estimate; |
| 1556 | if (sum_estimated > count) { |
| 1557 | estimate -= sum_estimated - count; |
| 1558 | sum_estimated = count; |
| 1559 | } |
| 1560 | |
| 1561 | if (estimate > 0) { |
| 1562 | if (child.GetStation() == next) { |
| 1563 | dest.InsertOrRetrieve(next).Update(estimate); |
| 1564 | } else { |
| 1565 | EstimateDestinations(cargo, source, child.GetStation(), estimate, dest); |
| 1566 | } |
| 1567 | } |
| 1568 | } |
| 1569 | |
| 1570 | } |
| 1571 | } |
| 1572 | } else { |
| 1573 | dest.InsertOrRetrieve(StationID::Invalid()).Update(count); |
| 1574 | } |
| 1575 | } |
| 1576 | |
| 1577 | /** |
| 1578 | * Build up the cargo view for PLANNED mode and a specific cargo. |
nothing calls this directly
no test coverage detected