# nodelist.hpp

Go to the documentation of this file.

    00001 /* $Id: nodelist.hpp 18826 2010-01-16 14:22:19Z frosch $ */
    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
    00022 template <class Titem_, int Thash_bits_open_, int Thash_bits_closed_>
    00023 class CNodeList_HashTableT {
    00024 public:
    00026   typedef Titem_ Titem;
    00028   typedef typename Titem_::Key Key;
    00030   typedef SmallArray<Titem_, 65536, 256> CItemArray;
    00032   typedef CHashTableT<Titem_, Thash_bits_open_  > COpenList;
    00034   typedef CHashTableT<Titem_, Thash_bits_closed_> CClosedList;
    00036   typedef CBinaryHeapT<Titem_> CPriorityQueue;
    00037
    00038 protected:
    00040   CItemArray            m_arr;
    00042   COpenList             m_open;
    00044   CClosedList           m_closed;
    00046   CPriorityQueue        m_open_queue;
    00048   Titem                *m_new_node;
    00049 public:
    00051   CNodeList_HashTableT()
    00052     : m_open_queue(204800)
    00053   {
    00054     m_new_node = NULL;
    00055   }
    00056
    00058   ~CNodeList_HashTableT()
    00059   {
    00060   }
    00061
    00063   FORCEINLINE int OpenCount()
    00064   {
    00065     return m_open.Count();
    00066   }
    00067
    00069   FORCEINLINE int ClosedCount()
    00070   {
    00071     return m_closed.Count();
    00072   }
    00073
    00075   FORCEINLINE Titem_ *CreateNewNode()
    00076   {
    00077     if (m_new_node == NULL) m_new_node = m_arr.AppendC();
    00078     return m_new_node;
    00079   }
    00080
    00082   FORCEINLINE void FoundBestNode(Titem_& item)
    00083   {
    00084     /* for now it is enough to invalidate m_new_node if it is our given node */
    00085     if (&item == m_new_node) {
    00086       m_new_node = NULL;
    00087     }
    00088     /* TODO: do we need to store best nodes found in some extra list/array? Probably not now. */
    00089   }
    00090
    00092   FORCEINLINE void InsertOpenNode(Titem_& item)
    00093   {
    00094     assert(m_closed.Find(item.GetKey()) == NULL);
    00095     m_open.Push(item);
    00096     /* TODO: check if m_open_queue is not full */
    00097     assert(!m_open_queue.IsFull());
    00098     m_open_queue.Push(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       Titem_& item = m_open_queue.GetHead();
    00109       return &item;
    00110     }
    00111     return NULL;
    00112   }
    00113
    00115   FORCEINLINE Titem_ *PopBestOpenNode()
    00116   {
    00117     if (!m_open_queue.IsEmpty()) {
    00118       Titem_& item = m_open_queue.PopHead();
    00119       m_open.Pop(item);
    00120       return &item;
    00121     }
    00122     return NULL;
    00123   }
    00124
    00126   FORCEINLINE Titem_ *FindOpenNode(const Key& key)
    00127   {
    00128     Titem_ *item = m_open.Find(key);
    00129     return item;
    00130   }
    00131
    00133   FORCEINLINE Titem_& PopOpenNode(const Key& key)
    00134   {
    00135     Titem_& item = m_open.Pop(key);
    00136     int idxPop = m_open_queue.FindLinear(item);
    00137     m_open_queue.RemoveByIdx(idxPop);
    00138     return item;
    00139   }
    00140
    00142   FORCEINLINE void InsertClosedNode(Titem_& item)
    00143   {
    00144     assert(m_open.Find(item.GetKey()) == NULL);
    00145     m_closed.Push(item);
    00146   }
    00147
    00149   FORCEINLINE Titem_ *FindClosedNode(const Key& key)
    00150   {
    00151     Titem_ *item = m_closed.Find(key);
    00152     return item;
    00153   }
    00154
    00155   FORCEINLINE int TotalCount() {return m_arr.Length();}
    00156   FORCEINLINE Titem_& ItemAt(int idx) {return m_arr[idx];}
    00157
    00158   template <class D> void Dump(D &dmp) const
    00159   {
    00160     dmp.WriteStructT("m_arr", &m_arr);
    00161   }
    00162 };
    00163
    00164 #endif /* NODELIST_HPP */