linkgraphjob.h

Go to the documentation of this file.
00001 /* $Id: linkgraphjob.h 26286 2014-01-29 19:55:29Z 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   void EraseFlows(NodeID from);
00068 
00069 public:
00070 
00075   class Edge : public LinkGraph::ConstEdge {
00076   private:
00077     EdgeAnnotation &anno; 
00078   public:
00084     Edge(const LinkGraph::BaseEdge &edge, EdgeAnnotation &anno) :
00085         LinkGraph::ConstEdge(edge), anno(anno) {}
00086 
00091     uint Demand() const { return this->anno.demand; }
00092 
00097     uint UnsatisfiedDemand() const { return this->anno.unsatisfied_demand; }
00098 
00103     uint Flow() const { return this->anno.flow; }
00104 
00109     void AddFlow(uint flow) { this->anno.flow += flow; }
00110 
00115     void RemoveFlow(uint flow)
00116     {
00117       assert(flow <= this->anno.flow);
00118       this->anno.flow -= flow;
00119     }
00120 
00125     void AddDemand(uint demand)
00126     {
00127       this->anno.demand += demand;
00128       this->anno.unsatisfied_demand += demand;
00129     }
00130 
00135     void SatisfyDemand(uint demand)
00136     {
00137       assert(demand <= this->anno.unsatisfied_demand);
00138       this->anno.unsatisfied_demand -= demand;
00139     }
00140   };
00141 
00145   class EdgeIterator : public LinkGraph::BaseEdgeIterator<const LinkGraph::BaseEdge, Edge, EdgeIterator> {
00146     EdgeAnnotation *base_anno; 
00147   public:
00154     EdgeIterator(const LinkGraph::BaseEdge *base, EdgeAnnotation *base_anno, NodeID current) :
00155         LinkGraph::BaseEdgeIterator<const LinkGraph::BaseEdge, Edge, EdgeIterator>(base, current),
00156         base_anno(base_anno) {}
00157 
00163     SmallPair<NodeID, Edge> operator*() const
00164     {
00165       return SmallPair<NodeID, Edge>(this->current, Edge(this->base[this->current], this->base_anno[this->current]));
00166     }
00167 
00173     FakePointer operator->() const {
00174       return FakePointer(this->operator*());
00175     }
00176   };
00177 
00182   class Node : public LinkGraph::ConstNode {
00183   private:
00184     NodeAnnotation &node_anno;  
00185     EdgeAnnotation *edge_annos; 
00186   public:
00187 
00193     Node (LinkGraphJob *lgj, NodeID node) :
00194       LinkGraph::ConstNode(&lgj->link_graph, node),
00195       node_anno(lgj->nodes[node]), edge_annos(lgj->edges[node])
00196     {}
00197 
00204     Edge operator[](NodeID to) const { return Edge(this->edges[to], this->edge_annos[to]); }
00205 
00211     EdgeIterator Begin() const { return EdgeIterator(this->edges, this->edge_annos, index); }
00212 
00218     EdgeIterator End() const { return EdgeIterator(this->edges, this->edge_annos, INVALID_NODE); }
00219 
00224     uint UndeliveredSupply() const { return this->node_anno.undelivered_supply; }
00225 
00230     FlowStatMap &Flows() { return this->node_anno.flows; }
00231 
00236     const FlowStatMap &Flows() const { return this->node_anno.flows; }
00237 
00243     PathList &Paths() { return this->node_anno.paths; }
00244 
00249     const PathList &Paths() const { return this->node_anno.paths; }
00250 
00256     void DeliverSupply(NodeID to, uint amount)
00257     {
00258       this->node_anno.undelivered_supply -= amount;
00259       (*this)[to].AddDemand(amount);
00260     }
00261   };
00262 
00267   LinkGraphJob() : settings(_settings_game.linkgraph), thread(NULL),
00268       join_date(INVALID_DATE) {}
00269 
00270   LinkGraphJob(const LinkGraph &orig);
00271   ~LinkGraphJob();
00272 
00273   void Init();
00274 
00279   inline bool IsFinished() const { return this->join_date <= _date; }
00280 
00285   inline Date JoinDate() const { return join_date; }
00286 
00291   inline void ShiftJoinDate(int interval) { this->join_date += interval; }
00292 
00297   inline const LinkGraphSettings &Settings() const { return this->settings; }
00298 
00304   inline Node operator[](NodeID num) { return Node(this, num); }
00305 
00310   inline uint Size() const { return this->link_graph.Size(); }
00311 
00316   inline CargoID Cargo() const { return this->link_graph.Cargo(); }
00317 
00322   inline Date LastCompression() const { return this->link_graph.LastCompression(); }
00323 
00328   inline LinkGraphID LinkGraphIndex() const { return this->link_graph.index; }
00329 
00334   inline const LinkGraph &Graph() const { return this->link_graph; }
00335 };
00336 
00337 #define FOR_ALL_LINK_GRAPH_JOBS(var) FOR_ALL_ITEMS_FROM(LinkGraphJob, link_graph_job_index, var, 0)
00338 
00342 class Path {
00343 public:
00344   Path(NodeID n, bool source = false);
00345 
00347   inline NodeID GetNode() const { return this->node; }
00348 
00350   inline NodeID GetOrigin() const { return this->origin; }
00351 
00353   inline Path *GetParent() { return this->parent; }
00354 
00356   inline uint GetCapacity() const { return this->capacity; }
00357 
00359   inline int GetFreeCapacity() const { return this->free_capacity; }
00360 
00368   inline static int GetCapacityRatio(int free, uint total)
00369   {
00370     return Clamp(free, PATH_CAP_MIN_FREE, PATH_CAP_MAX_FREE) * PATH_CAP_MULTIPLIER / max(total, 1U);
00371   }
00372 
00377   inline int GetCapacityRatio() const
00378   {
00379     return Path::GetCapacityRatio(this->free_capacity, this->capacity);
00380   }
00381 
00383   inline uint GetDistance() const { return this->distance; }
00384 
00386   inline void ReduceFlow(uint f) { this->flow -= f; }
00387 
00389   inline void AddFlow(uint f) { this->flow += f; }
00390 
00392   inline uint GetFlow() const { return this->flow; }
00393 
00395   inline uint GetNumChildren() const { return this->num_children; }
00396 
00400   inline void Detach()
00401   {
00402     if (this->parent != NULL) {
00403       this->parent->num_children--;
00404       this->parent = NULL;
00405     }
00406   }
00407 
00408   uint AddFlow(uint f, LinkGraphJob &job, uint max_saturation);
00409   void Fork(Path *base, uint cap, int free_cap, uint dist);
00410 
00411 protected:
00412 
00416   enum PathCapacityBoundaries {
00417     PATH_CAP_MULTIPLIER = 16,
00418     PATH_CAP_MIN_FREE = (INT_MIN + 1) / PATH_CAP_MULTIPLIER,
00419     PATH_CAP_MAX_FREE = (INT_MAX - 1) / PATH_CAP_MULTIPLIER
00420   };
00421 
00422   uint distance;     
00423   uint capacity;     
00424   int free_capacity; 
00425   uint flow;         
00426   NodeID node;       
00427   NodeID origin;     
00428   uint num_children; 
00429   Path *parent;      
00430 };
00431 
00432 #endif /* LINKGRAPHJOB_H */