linkgraphjob.h

00001 /* $Id$ */
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   const 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 
00240     PathList &Paths() { return this->node_anno.paths; }
00241 
00246     const PathList &Paths() const { return this->node_anno.paths; }
00247 
00253     void DeliverSupply(NodeID to, uint amount)
00254     {
00255       this->node_anno.undelivered_supply -= amount;
00256       (*this)[to].AddDemand(amount);
00257     }
00258   };
00259 
00264   LinkGraphJob() : settings(_settings_game.linkgraph), thread(NULL),
00265       join_date(INVALID_DATE) {}
00266 
00267   LinkGraphJob(const LinkGraph &orig);
00268   ~LinkGraphJob();
00269 
00270   void Init();
00271 
00276   inline bool IsFinished() const { return this->join_date <= _date; }
00277 
00282   inline Date JoinDate() const { return join_date; }
00283 
00288   inline const LinkGraphSettings &Settings() const { return this->settings; }
00289 
00295   inline Node operator[](NodeID num) { return Node(this, num); }
00296 
00301   inline uint Size() const { return this->link_graph.Size(); }
00302 
00307   inline CargoID Cargo() const { return this->link_graph.Cargo(); }
00308 
00313   inline Date LastCompression() const { return this->link_graph.LastCompression(); }
00314 
00319   inline LinkGraphID LinkGraphIndex() const { return this->link_graph.index; }
00320 
00325   inline const LinkGraph &Graph() const { return this->link_graph; }
00326 };
00327 
00328 #define FOR_ALL_LINK_GRAPH_JOBS(var) FOR_ALL_ITEMS_FROM(LinkGraphJob, link_graph_job_index, var, 0)
00329 
00333 class Path {
00334 public:
00335   Path(NodeID n, bool source = false);
00336 
00338   inline NodeID GetNode() const { return this->node; }
00339 
00341   inline NodeID GetOrigin() const { return this->origin; }
00342 
00344   inline Path *GetParent() { return this->parent; }
00345 
00347   inline uint GetCapacity() const { return this->capacity; }
00348 
00350   inline int GetFreeCapacity() const { return this->free_capacity; }
00351 
00359   inline static int GetCapacityRatio(int free, int total)
00360   {
00361     return (free << 4) / (total + 1);
00362   }
00363 
00368   inline int GetCapacityRatio() const
00369   {
00370     return Path::GetCapacityRatio(this->free_capacity, this->capacity);
00371   }
00372 
00374   inline uint GetDistance() const { return this->distance; }
00375 
00377   inline void ReduceFlow(uint f) { this->flow -= f; }
00378 
00380   inline void AddFlow(uint f) { this->flow += f; }
00381 
00383   inline uint GetFlow() const { return this->flow; }
00384 
00386   inline uint GetNumChildren() const { return this->num_children; }
00387 
00391   inline void Detach()
00392   {
00393     if (this->parent != NULL) {
00394       this->parent->num_children--;
00395       this->parent = NULL;
00396     }
00397   }
00398 
00399   uint AddFlow(uint f, LinkGraphJob &job, uint max_saturation);
00400   void Fork(Path *base, uint cap, int free_cap, uint dist);
00401 
00402 protected:
00403   uint distance;     
00404   uint capacity;     
00405   int free_capacity; 
00406   uint flow;         
00407   NodeID node;       
00408   NodeID origin;     
00409   uint num_children; 
00410   Path *parent;      
00411 };
00412 
00413 #endif /* LINKGRAPHJOB_H */