00001 /* $Id: nodelist.hpp 21594 2010-12-22 11:24:38Z alberth $ */ 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 00154 FORCEINLINE int TotalCount() {return m_arr.Length();} 00155 FORCEINLINE Titem_& ItemAt(int idx) {return m_arr[idx];} 00156 00157 template <class D> void Dump(D &dmp) const 00158 { 00159 dmp.WriteStructT("m_arr", &m_arr); 00160 } 00161 }; 00162 00163 #endif /* NODELIST_HPP */