00001 /* $Id: nodelist.hpp 14949 2009-01-10 00:31:47Z 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 } 00050 ~CNodeList_HashTableT() 00051 { 00052 } 00054 FORCEINLINE int OpenCount() {return m_open.Count();} 00056 FORCEINLINE int ClosedCount() {return m_closed.Count();} 00058 FORCEINLINE Titem_ *CreateNewNode() 00059 { 00060 if (m_new_node == NULL) m_new_node = &m_arr.Add(); 00061 return m_new_node; 00062 } 00064 FORCEINLINE void FoundBestNode(Titem_& item) 00065 { 00066 // for now it is enough to invalidate m_new_node if it is our given node 00067 if (&item == m_new_node) 00068 m_new_node = NULL; 00069 // TODO: do we need to store best nodes found in some extra list/array? Probably not now. 00070 } 00072 FORCEINLINE void InsertOpenNode(Titem_& item) 00073 { 00074 assert(m_closed.Find(item.GetKey()) == NULL); 00075 m_open.Push(item); 00076 // TODO: check if m_open_queue is not full 00077 assert(!m_open_queue.IsFull()); 00078 m_open_queue.Push(item); 00079 if (&item == m_new_node) 00080 m_new_node = NULL; 00081 } 00083 FORCEINLINE Titem_ *GetBestOpenNode() 00084 { 00085 if (!m_open_queue.IsEmpty()) { 00086 Titem_& item = m_open_queue.GetHead(); 00087 return &item; 00088 } 00089 return NULL; 00090 } 00092 FORCEINLINE Titem_ *PopBestOpenNode() 00093 { 00094 if (!m_open_queue.IsEmpty()) { 00095 Titem_& item = m_open_queue.PopHead(); 00096 m_open.Pop(item); 00097 return &item; 00098 } 00099 return NULL; 00100 } 00102 FORCEINLINE Titem_ *FindOpenNode(const Key& key) 00103 { 00104 Titem_ *item = m_open.Find(key); 00105 return item; 00106 } 00108 FORCEINLINE Titem_& PopOpenNode(const Key& key) 00109 { 00110 Titem_& item = m_open.Pop(key); 00111 int idxPop = m_open_queue.FindLinear(item); 00112 m_open_queue.RemoveByIdx(idxPop); 00113 return item; 00114 } 00116 FORCEINLINE void InsertClosedNode(Titem_& item) 00117 { 00118 assert(m_open.Find(item.GetKey()) == NULL); 00119 m_closed.Push(item); 00120 } 00122 FORCEINLINE Titem_ *FindClosedNode(const Key& key) 00123 { 00124 Titem_ *item = m_closed.Find(key); 00125 return item; 00126 } 00127 00128 FORCEINLINE int TotalCount() {return m_arr.Size();} 00129 FORCEINLINE Titem_& ItemAt(int idx) {return m_arr[idx];} 00130 00131 template <class D> void Dump(D &dmp) const 00132 { 00133 dmp.WriteStructT("m_arr", &m_arr); 00134 } 00135 }; 00136 00137 #endif /* NODELIST_HPP */