nodelist.hpp

Go to the documentation of this file.
00001 /* $Id: nodelist.hpp 15718 2009-03-15 00:32:18Z rubidium $ */
00002 
00005 #ifndef  NODELIST_HPP
00006 #define  NODELIST_HPP
00007 
00008 #include "../misc/array.hpp"
00009 #include "../misc/hashtable.hpp"
00010 #include "../misc/binaryheap.hpp"
00011 
00015 template <class Titem_, int Thash_bits_open_, int Thash_bits_closed_>
00016 class CNodeList_HashTableT {
00017 public:
00019   typedef Titem_ Titem;
00021   typedef typename Titem_::Key Key;
00023   typedef CArrayT<Titem_, 65536, 256> CItemArray;
00025   typedef CHashTableT<Titem_, Thash_bits_open_  > COpenList;
00027   typedef CHashTableT<Titem_, Thash_bits_closed_> CClosedList;
00029   typedef CBinaryHeapT<Titem_> CPriorityQueue;
00030 
00031 protected:
00033   CItemArray            m_arr;
00035   COpenList             m_open;
00037   CClosedList           m_closed;
00039   CPriorityQueue        m_open_queue;
00041   Titem                *m_new_node;
00042 public:
00044   CNodeList_HashTableT()
00045     : m_open_queue(204800)
00046   {
00047     m_new_node = NULL;
00048   }
00049 
00051   ~CNodeList_HashTableT()
00052   {
00053   }
00054 
00056   FORCEINLINE int OpenCount()
00057   {
00058     return m_open.Count();
00059   }
00060 
00062   FORCEINLINE int ClosedCount()
00063   {
00064     return m_closed.Count();
00065   }
00066 
00068   FORCEINLINE Titem_ *CreateNewNode()
00069   {
00070     if (m_new_node == NULL) m_new_node = &m_arr.Add();
00071     return m_new_node;
00072   }
00073 
00075   FORCEINLINE void FoundBestNode(Titem_& item)
00076   {
00077     /* for now it is enough to invalidate m_new_node if it is our given node */
00078     if (&item == m_new_node) {
00079       m_new_node = NULL;
00080     }
00081     /* TODO: do we need to store best nodes found in some extra list/array? Probably not now. */
00082   }
00083 
00085   FORCEINLINE void InsertOpenNode(Titem_& item)
00086   {
00087     assert(m_closed.Find(item.GetKey()) == NULL);
00088     m_open.Push(item);
00089     /* TODO: check if m_open_queue is not full */
00090     assert(!m_open_queue.IsFull());
00091     m_open_queue.Push(item);
00092     if (&item == m_new_node) {
00093       m_new_node = NULL;
00094     }
00095   }
00096 
00098   FORCEINLINE Titem_ *GetBestOpenNode()
00099   {
00100     if (!m_open_queue.IsEmpty()) {
00101       Titem_& item = m_open_queue.GetHead();
00102       return &item;
00103     }
00104     return NULL;
00105   }
00106 
00108   FORCEINLINE Titem_ *PopBestOpenNode()
00109   {
00110     if (!m_open_queue.IsEmpty()) {
00111       Titem_& item = m_open_queue.PopHead();
00112       m_open.Pop(item);
00113       return &item;
00114     }
00115     return NULL;
00116   }
00117 
00119   FORCEINLINE Titem_ *FindOpenNode(const Key& key)
00120   {
00121     Titem_ *item = m_open.Find(key);
00122     return item;
00123   }
00124 
00126   FORCEINLINE Titem_& PopOpenNode(const Key& key)
00127   {
00128     Titem_& item = m_open.Pop(key);
00129     int idxPop = m_open_queue.FindLinear(item);
00130     m_open_queue.RemoveByIdx(idxPop);
00131     return item;
00132   }
00133 
00135   FORCEINLINE void InsertClosedNode(Titem_& item)
00136   {
00137     assert(m_open.Find(item.GetKey()) == NULL);
00138     m_closed.Push(item);
00139   }
00140 
00142   FORCEINLINE Titem_ *FindClosedNode(const Key& key)
00143   {
00144     Titem_ *item = m_closed.Find(key);
00145     return item;
00146   }
00147 
00148   FORCEINLINE int TotalCount() {return m_arr.Size();}
00149   FORCEINLINE Titem_& ItemAt(int idx) {return m_arr[idx];}
00150 
00151   template <class D> void Dump(D &dmp) const
00152   {
00153     dmp.WriteStructT("m_arr", &m_arr);
00154   }
00155 };
00156 
00157 #endif /* NODELIST_HPP */

Generated on Wed Jun 3 19:05:17 2009 for OpenTTD by  doxygen 1.5.6