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 */