linkgraph.h

Go to the documentation of this file.
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 LINKGRAPH_H
00013 #define LINKGRAPH_H
00014 
00015 #include "../core/pool_type.hpp"
00016 #include "../core/smallmap_type.hpp"
00017 #include "../core/smallmatrix_type.hpp"
00018 #include "../station_base.h"
00019 #include "../cargotype.h"
00020 #include "../date_func.h"
00021 #include "linkgraph_type.h"
00022 
00023 struct SaveLoad;
00024 class LinkGraph;
00025 
00030 typedef Pool<LinkGraph, LinkGraphID, 32, 0xFFFFFF> LinkGraphPool;
00032 extern LinkGraphPool _link_graph_pool;
00033 
00040 class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> {
00041 public:
00042 
00048   struct BaseNode {
00049     uint supply;             
00050     uint demand;             
00051     StationID station;       
00052     Date last_update;        
00053     void Init(StationID st = INVALID_STATION, uint demand = 0);
00054   };
00055 
00062   struct BaseEdge {
00063     uint distance;    
00064     uint capacity;    
00065     uint usage;       
00066     Date last_update; 
00067     NodeID next_edge; 
00068     void Init(uint distance = 0);
00069   };
00070 
00075   template<typename Tedge>
00076   class EdgeWrapper {
00077   protected:
00078     Tedge &edge; 
00079 
00080   public:
00081 
00086     EdgeWrapper (Tedge &edge) : edge(edge) {}
00087 
00092     uint Capacity() const { return this->edge.capacity; }
00093 
00098     uint Usage() const { return this->edge.usage; }
00099 
00104     uint Distance() const { return this->edge.distance; }
00105 
00110     Date LastUpdate() const { return this->edge.last_update; }
00111   };
00112 
00118   template<typename Tnode, typename Tedge>
00119   class NodeWrapper {
00120   protected:
00121     Tnode &node;  
00122     Tedge *edges; 
00123     NodeID index; 
00124 
00125   public:
00126 
00133     NodeWrapper(Tnode &node, Tedge *edges, NodeID index) : node(node),
00134       edges(edges), index(index) {}
00135 
00140     uint Supply() const { return this->node.supply; }
00141 
00146     uint Demand() const { return this->node.demand; }
00147 
00152     StationID Station() const { return this->node.station; }
00153 
00158     Date LastUpdate() const { return this->node.last_update; }
00159   };
00160 
00168   template <class Tedge, class Tedge_wrapper, class Titer>
00169   class BaseEdgeIterator {
00170   protected:
00171     Tedge *base;    
00172     NodeID current; 
00173 
00180     class FakePointer : public SmallPair<NodeID, Tedge_wrapper> {
00181     public:
00182 
00187       FakePointer(const SmallPair<NodeID, Tedge_wrapper> &pair) : SmallPair<NodeID, Tedge_wrapper>(pair) {}
00188 
00193       SmallPair<NodeID, Tedge_wrapper> *operator->() { return this; }
00194     };
00195 
00196   public:
00202     BaseEdgeIterator (Tedge *base, NodeID current) :
00203       base(base),
00204       current(current == INVALID_NODE ? current : base[current].next_edge)
00205     {}
00206 
00211     Titer &operator++()
00212     {
00213       this->current = this->base[this->current].next_edge;
00214       return static_cast<Titer &>(*this);
00215     }
00216 
00221     Titer operator++(int)
00222     {
00223       Titer ret(static_cast<Titer &>(*this));
00224       this->current = this->base[this->current].next_edge;
00225       return ret;
00226     }
00227 
00235     template<class Tother>
00236     bool operator==(const Tother &other)
00237     {
00238       return this->base == other.base && this->current == other.current;
00239     }
00240 
00248     template<class Tother>
00249     bool operator!=(const Tother &other)
00250     {
00251       return this->base != other.base || this->current != other.current;
00252     }
00253 
00258     SmallPair<NodeID, Tedge_wrapper> operator*() const
00259     {
00260       return SmallPair<NodeID, Tedge_wrapper>(this->current, Tedge_wrapper(this->base[this->current]));
00261     }
00262 
00267     FakePointer operator->() const {
00268       return FakePointer(this->operator*());
00269     }
00270   };
00271 
00275   typedef EdgeWrapper<const BaseEdge> ConstEdge;
00276 
00280   class Edge : public EdgeWrapper<BaseEdge> {
00281   public:
00286     Edge(BaseEdge &edge) : EdgeWrapper<BaseEdge>(edge) {}
00287     void Update(uint capacity, uint usage);
00288   };
00289 
00294   class ConstEdgeIterator : public BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator> {
00295   public:
00301     ConstEdgeIterator(const BaseEdge *edges, NodeID current) :
00302       BaseEdgeIterator<const BaseEdge, ConstEdge, ConstEdgeIterator>(edges, current) {}
00303   };
00304 
00309   class EdgeIterator : public BaseEdgeIterator<BaseEdge, Edge, EdgeIterator> {
00310   public:
00316     EdgeIterator(BaseEdge *edges, NodeID current) :
00317       BaseEdgeIterator<BaseEdge, Edge, EdgeIterator>(edges, current) {}
00318   };
00319 
00324   class ConstNode : public NodeWrapper<const BaseNode, const BaseEdge> {
00325   public:
00331     ConstNode(const LinkGraph *lg, NodeID node) :
00332       NodeWrapper<const BaseNode, const BaseEdge>(lg->nodes[node], lg->edges[node], node)
00333     {}
00334 
00341     ConstEdge operator[](NodeID to) const { return ConstEdge(this->edges[to]); }
00342 
00347     ConstEdgeIterator Begin() const { return ConstEdgeIterator(this->edges, this->index); }
00348 
00353     ConstEdgeIterator End() const { return ConstEdgeIterator(this->edges, INVALID_NODE); }
00354   };
00355 
00359   class Node : public NodeWrapper<BaseNode, BaseEdge> {
00360   public:
00366     Node(LinkGraph *lg, NodeID node) :
00367       NodeWrapper<BaseNode, BaseEdge>(lg->nodes[node], lg->edges[node], node)
00368     {}
00369 
00376     Edge operator[](NodeID to) { return Edge(this->edges[to]); }
00377 
00382     EdgeIterator Begin() { return EdgeIterator(this->edges, this->index); }
00383 
00388     EdgeIterator End() { return EdgeIterator(this->edges, INVALID_NODE); }
00389 
00394     void UpdateSupply(uint supply)
00395     {
00396       this->node.supply += supply;
00397       this->node.last_update = _date;
00398     }
00399 
00404     void SetDemand(uint demand)
00405     {
00406       this->node.demand = demand;
00407     }
00408 
00409     void AddEdge(NodeID to, uint capacity, uint usage = 0);
00410     void UpdateEdge(NodeID to, uint capacity, uint usage = 0);
00411     void RemoveEdge(NodeID to);
00412   };
00413 
00414   typedef SmallVector<BaseNode, 16> NodeVector;
00415   typedef SmallMatrix<BaseEdge> EdgeMatrix;
00416 
00418   static const uint MIN_TIMEOUT_DISTANCE = 48;
00419 
00421   static const uint COMPRESSION_INTERVAL = 256;
00422 
00431   inline static uint Scale(uint val, uint target_age, uint orig_age)
00432   {
00433     return val > 0 ? max(1U, val * target_age / orig_age) : 0;
00434   }
00435 
00437   LinkGraph() : cargo(INVALID_CARGO), last_compression(0) {}
00442   LinkGraph(CargoID cargo) : cargo(cargo), last_compression(_date) {}
00443 
00444   void Init(uint size);
00445   void Compress();
00446   void Merge(LinkGraph *other);
00447 
00448   /* Splitting link graphs is intentionally not implemented.
00449    * The overhead in determining connectedness would probably outweigh the
00450    * benefit of having to deal with smaller graphs. In real world examples
00451    * networks generally grow. Only rarely a network is permanently split.
00452    * Reacting to temporary splits here would obviously create performance
00453    * problems and detecting the temporary or permanent nature of splits isn't
00454    * trivial. */
00455 
00461   inline Node operator[](NodeID num) { return Node(this, num); }
00462 
00468   inline ConstNode operator[](NodeID num) const { return ConstNode(this, num); }
00469 
00474   inline uint Size() const { return this->nodes.Length(); }
00475 
00480   inline Date LastCompression() const { return this->last_compression; }
00481 
00486   inline CargoID Cargo() const { return this->cargo; }
00487 
00493   inline uint Monthly(uint base) const
00494   {
00495     return base * 30 / (_date - this->last_compression + 1);
00496   }
00497 
00498   NodeID AddNode(const Station *st);
00499   void RemoveNode(NodeID id);
00500 
00501 protected:
00502   friend class LinkGraph::ConstNode;
00503   friend class LinkGraph::Node;
00504   friend const SaveLoad *GetLinkGraphDesc();
00505   friend const SaveLoad *GetLinkGraphJobDesc();
00506   friend void SaveLoad_LinkGraph(LinkGraph &lg);
00507 
00508   CargoID cargo;         
00509   Date last_compression; 
00510   NodeVector nodes;      
00511   EdgeMatrix edges;      
00512 };
00513 
00514 #define FOR_ALL_LINK_GRAPHS(var) FOR_ALL_ITEMS_FROM(LinkGraph, link_graph_index, var, 0)
00515 
00516 #endif /* LINKGRAPH_H */