linkgraphjob.h

Go to the documentation of this file.
00001 /* $Id: linkgraphjob.h 25885 2013-10-19 17:15:19Z fonsinchen $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef LINKGRAPHJOB_H
00013 #define LINKGRAPHJOB_H
00014 
00015 #include "../thread/thread.h"
00016 #include "linkgraph.h"
00017 #include <list>
00018 
00019 class LinkGraphJob;
00020 class Path;
00021 typedef std::list<Path *> PathList;
00022 
00024 typedef Pool<LinkGraphJob, LinkGraphJobID, 32, 0xFFFFFF> LinkGraphJobPool;
00026 extern LinkGraphJobPool _link_graph_job_pool;
00027 
00031 class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{
00032 private:
00036   struct EdgeAnnotation {
00037     uint demand;             
00038     uint unsatisfied_demand; 
00039     uint flow;               
00040     void Init();
00041   };
00042 
00046   struct NodeAnnotation {
00047     uint undelivered_supply; 
00048     PathList paths;          
00049     FlowStatMap flows;       
00050     void Init(uint supply);
00051   };
00052 
00053   typedef SmallVector<NodeAnnotation, 16> NodeAnnotationVector;
00054   typedef SmallMatrix<EdgeAnnotation> EdgeAnnotationMatrix;
00055 
00056   friend const SaveLoad *GetLinkGraphJobDesc();
00057   friend class LinkGraphSchedule;
00058 
00059 protected:
00060   const LinkGraph link_graph;       
00061   const LinkGraphSettings settings; 
00062   ThreadObject *thread;             
00063   Date join_date;                   
00064   NodeAnnotationVector nodes;       
00065   EdgeAnnotationMatrix edges;       
00066 
00067 public:
00068 
00073   class Edge : public LinkGraph::ConstEdge {
00074   private:
00075     EdgeAnnotation &anno; 
00076   public:
00082     Edge(const LinkGraph::BaseEdge &edge, EdgeAnnotation &anno) :
00083         LinkGraph::ConstEdge(edge), anno(anno) {}
00084 
00089     uint Demand() const { return this->anno.demand; }
00090 
00095     uint UnsatisfiedDemand() const { return this->anno.unsatisfied_demand; }
00096 
00101     uint Flow() const { return this->anno.flow; }
00102 
00107     void AddFlow(uint flow) { this->anno.flow += flow; }
00108 
00113     void RemoveFlow(uint flow)
00114     {
00115       assert(flow <= this->anno.flow);
00116       this->anno.flow -= flow;
00117     }
00118 
00123     void AddDemand(uint demand)
00124     {
00125       this->anno.demand += demand;
00126       this->anno.unsatisfied_demand += demand;
00127     }
00128 
00133     void SatisfyDemand(uint demand)
00134     {
00135       assert(demand <= this->anno.unsatisfied_demand);
00136       this->anno.unsatisfied_demand -= demand;
00137     }
00138   };
00139 
00143   class EdgeIterator : public LinkGraph::BaseEdgeIterator<const LinkGraph::BaseEdge, Edge, EdgeIterator> {
00144     EdgeAnnotation *base_anno; 
00145   public:
00152     EdgeIterator(const LinkGraph::BaseEdge *base, EdgeAnnotation *base_anno, NodeID current) :
00153         LinkGraph::BaseEdgeIterator<const LinkGraph::BaseEdge, Edge, EdgeIterator>(base, current),
00154         base_anno(base_anno) {}
00155 
00161     SmallPair<NodeID, Edge> operator*() const
00162     {
00163       return SmallPair<NodeID, Edge>(this->current, Edge(this->base[this->current], this->base_anno[this->current]));
00164     }
00165 
00171     FakePointer operator->() const {
00172       return FakePointer(this->operator*());
00173     }
00174   };
00175 
00180   class Node : public LinkGraph::ConstNode {
00181   private:
00182     NodeAnnotation &node_anno;  
00183     EdgeAnnotation *edge_annos; 
00184   public:
00185 
00191     Node (LinkGraphJob *lgj, NodeID node) :
00192       LinkGraph::ConstNode(&lgj->link_graph, node),
00193       node_anno(lgj->nodes[node]), edge_annos(lgj->edges[node])
00194     {}
00195 
00202     Edge operator[](NodeID to) const { return Edge(this->edges[to], this->edge_annos[to]); }
00203 
00209     EdgeIterator Begin() const { return EdgeIterator(this->edges, this->edge_annos, index); }
00210 
00216     EdgeIterator End() const { return EdgeIterator(this->edges, this->edge_annos, INVALID_NODE); }
00217 
00222     uint UndeliveredSupply() const { return this->node_anno.undelivered_supply; }
00223 
00228     FlowStatMap &Flows() { return this->node_anno.flows; }
00229 
00234     const FlowStatMap &Flows() const { return this->node_anno.flows; }
00235 
00241     PathList &Paths() { return this->node_anno.paths; }
00242 
00247     const PathList &Paths() const { return this->node_anno.paths; }
00248 
00254     void DeliverSupply(NodeID to, uint amount)
00255     {
00256       this->node_anno.undelivered_supply -= amount;
00257       (*this)[to].AddDemand(amount);
00258     }
00259   };
00260 
00265   LinkGraphJob() : settings(_settings_game.linkgraph), thread(NULL),
00266       join_date(INVALID_DATE) {}
00267 
00268   LinkGraphJob(const LinkGraph &orig);
00269   ~LinkGraphJob();
00270 
00271   void Init();
00272 
00277   inline bool IsFinished() const { return this->join_date <= _date; }
00278 
00283   inline Date JoinDate() const { return join_date; }
00284 
00289   inline void ShiftJoinDate(int interval) { this->join_date += interval; }
00290 
00295   inline const LinkGraphSettings &Settings() const { return this->settings; }
00296 
00302   inline Node operator[](NodeID num) { return Node(this, num); }
00303 
00308   inline uint Size() const { return this->link_graph.Size(); }
00309 
00314   inline CargoID Cargo() const { return this->link_graph.Cargo(); }
00315 
00320   inline Date LastCompression() const { return this->link_graph.LastCompression(); }
00321 
00326   inline LinkGraphID LinkGraphIndex() const { return this->link_graph.index; }
00327 
00332   inline const LinkGraph &Graph() const { return this->link_graph; }
00333 };
00334 
00335 #define FOR_ALL_LINK_GRAPH_JOBS(var) FOR_ALL_ITEMS_FROM(LinkGraphJob, link_graph_job_index, var, 0)
00336 
00340 class Path {
00341 public:
00342   Path(NodeID n, bool source = false);
00343 
00345   inline NodeID GetNode() const { return this->node; }
00346 
00348   inline NodeID GetOrigin() const { return this->origin; }
00349 
00351   inline Path *GetParent() { return this->parent; }
00352 
00354   inline uint GetCapacity() const { return this->capacity; }
00355 
00357   inline int GetFreeCapacity() const { return this->free_capacity; }
00358 
00366   inline static int GetCapacityRatio(int free, uint total)
00367   {
00368     return Clamp(free, PATH_CAP_MIN_FREE, PATH_CAP_MAX_FREE) * PATH_CAP_MULTIPLIER / max(total, 1U);
00369   }
00370 
00375   inline int GetCapacityRatio() const
00376   {
00377     return Path::GetCapacityRatio(this->free_capacity, this->capacity);
00378   }
00379 
00381   inline uint GetDistance() const { return this->distance; }
00382 
00384   inline void ReduceFlow(uint f) { this->flow -= f; }
00385 
00387   inline void AddFlow(uint f) { this->flow += f; }
00388 
00390   inline uint GetFlow() const { return this->flow; }
00391 
00393   inline uint GetNumChildren() const { return this->num_children; }
00394 
00398   inline void Detach()
00399   {
00400     if (this->parent != NULL) {
00401       this->parent->num_children--;
00402       this->parent = NULL;
00403     }
00404   }
00405 
00406   uint AddFlow(uint f, LinkGraphJob &job, uint max_saturation);
00407   void Fork(Path *base, uint cap, int free_cap, uint dist);
00408 
00409 protected:
00410 
00414   enum PathCapacityBoundaries {
00415     PATH_CAP_MULTIPLIER = 16,
00416     PATH_CAP_MIN_FREE = (INT_MIN + 1) / PATH_CAP_MULTIPLIER,
00417     PATH_CAP_MAX_FREE = (INT_MAX - 1) / PATH_CAP_MULTIPLIER
00418   };
00419 
00420   uint distance;     
00421   uint capacity;     
00422   int free_capacity; 
00423   uint flow;         
00424   NodeID node;       
00425   NodeID origin;     
00426   uint num_children; 
00427   Path *parent;      
00428 };
00429 
00430 #endif /* LINKGRAPHJOB_H */