nodelist.hpp

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 NODELIST_HPP
00013 #define NODELIST_HPP
00014 
00015 #include "../../misc/array.hpp"
00016 #include "../../misc/hashtable.hpp"
00017 #include "../../misc/binaryheap.hpp"
00018 
00024 template <class Titem_, int Thash_bits_open_, int Thash_bits_closed_>
00025 class CNodeList_HashTableT {
00026 public:
00028   typedef Titem_ Titem;
00030   typedef typename Titem_::Key Key;
00032   typedef SmallArray<Titem_, 65536, 256> CItemArray;
00034   typedef CHashTableT<Titem_, Thash_bits_open_  > COpenList;
00036   typedef CHashTableT<Titem_, Thash_bits_closed_> CClosedList;
00038   typedef CBinaryHeapT<Titem_> CPriorityQueue;
00039 
00040 protected:
00042   CItemArray            m_arr;
00044   COpenList             m_open;
00046   CClosedList           m_closed;
00048   CPriorityQueue        m_open_queue;
00050   Titem                *m_new_node;
00051 public:
00053   CNodeList_HashTableT()
00054     : m_open_queue(2048)
00055   {
00056     m_new_node = NULL;
00057   }
00058 
00060   ~CNodeList_HashTableT()
00061   {
00062   }
00063 
00065   FORCEINLINE int OpenCount()
00066   {
00067     return m_open.Count();
00068   }
00069 
00071   FORCEINLINE int ClosedCount()
00072   {
00073     return m_closed.Count();
00074   }
00075 
00077   FORCEINLINE Titem_ *CreateNewNode()
00078   {
00079     if (m_new_node == NULL) m_new_node = m_arr.AppendC();
00080     return m_new_node;
00081   }
00082 
00084   FORCEINLINE void FoundBestNode(Titem_& item)
00085   {
00086     /* for now it is enough to invalidate m_new_node if it is our given node */
00087     if (&item == m_new_node) {
00088       m_new_node = NULL;
00089     }
00090     /* TODO: do we need to store best nodes found in some extra list/array? Probably not now. */
00091   }
00092 
00094   FORCEINLINE void InsertOpenNode(Titem_& item)
00095   {
00096     assert(m_closed.Find(item.GetKey()) == NULL);
00097     m_open.Push(item);
00098     m_open_queue.Include(&item);
00099     if (&item == m_new_node) {
00100       m_new_node = NULL;
00101     }
00102   }
00103 
00105   FORCEINLINE Titem_ *GetBestOpenNode()
00106   {
00107     if (!m_open_queue.IsEmpty()) {
00108       return m_open_queue.Begin();
00109     }
00110     return NULL;
00111   }
00112 
00114   FORCEINLINE Titem_ *PopBestOpenNode()
00115   {
00116     if (!m_open_queue.IsEmpty()) {
00117       Titem_ *item = m_open_queue.Shift();
00118       m_open.Pop(*item);
00119       return item;
00120     }
00121     return NULL;
00122   }
00123 
00125   FORCEINLINE Titem_ *FindOpenNode(const Key& key)
00126   {
00127     Titem_ *item = m_open.Find(key);
00128     return item;
00129   }
00130 
00132   FORCEINLINE Titem_& PopOpenNode(const Key& key)
00133   {
00134     Titem_& item = m_open.Pop(key);
00135     uint idxPop = m_open_queue.FindIndex(item);
00136     m_open_queue.Remove(idxPop);
00137     return item;
00138   }
00139 
00141   FORCEINLINE void InsertClosedNode(Titem_& item)
00142   {
00143     assert(m_open.Find(item.GetKey()) == NULL);
00144     m_closed.Push(item);
00145   }
00146 
00148   FORCEINLINE Titem_ *FindClosedNode(const Key& key)
00149   {
00150     Titem_ *item = m_closed.Find(key);
00151     return item;
00152   }
00153 
00155   FORCEINLINE int TotalCount() {return m_arr.Length();}
00157   FORCEINLINE Titem_& ItemAt(int idx) {return m_arr[idx];}
00158 
00160   template <class D> void Dump(D &dmp) const
00161   {
00162     dmp.WriteStructT("m_arr", &m_arr);
00163   }
00164 };
00165 
00166 #endif /* NODELIST_HPP */