# 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 <set>
    00018
    00019 class LinkGraphJob;
    00020 class Path;
    00021 typedef std::set<Path *> PathSet;
    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     PathSet 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     PathSet &Paths() { return this->node_anno.paths; }
    00241
    00246     const PathSet &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 */