nskiplist.hpp

Go to the documentation of this file.
00001 // LICENSE: (Please see the file COPYING for details)
00002 //
00003 // NUS - Nemesis Utilities System: A C++ application development framework 
00004 // Copyright (C) 2006, 2008 Otavio Rodolfo Piske
00005 //
00006 //  This file is part of NUS
00007 //
00008 //  This library is free software; you can redistribute it and/or
00009 //  modify it under the terms of the GNU Lesser General Public
00010 //  License as published by the Free Software Foundation version 2.1
00011 //  of the License.
00012 //
00013 //  This library is distributed in the hope that it will be useful,
00014 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 //  Lesser General Public License for more details.
00017 //
00018 //  You should have received a copy of the GNU Lesser General Public
00019 //  License along with this library; if not, write to the Free Software
00020 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021 //
00022 #ifndef NSKIPLIST_HPP
00023 #define NSKIPLIST_HPP
00024 
00036 template <typename T>
00037 class NSkipList {
00038       public:
00039             class iterator;
00040             
00044             typedef const iterator const_iterator;
00045             
00050             NSkipList(void);
00051             
00057             NSkipList(nint32 max);
00058       
00062             ~NSkipList(void);
00063             
00068             bool isEmpty(void) const;
00069             
00074             nint32 getHeight(void) const;
00075             
00080             nint32 getCurrentHeight(void) const;
00081             
00088             bool erase(const T &key);
00089             
00097             bool contains(const T &key) const;
00098             
00103             nuint64 size(void) const;
00104             
00109             nuint64 count(void) const;
00110             
00117             iterator begin(void) ;
00118             
00125             const_iterator constBegin(void) const;
00126             
00133             iterator end(void);
00134             
00141             const_iterator constEnd(void) const;
00142             
00148             iterator find(const T &key);
00149             
00155             const_iterator find_const(const T &key) const;
00156             
00163             iterator insert(const T &key);
00164             
00168             void clear(void);
00169             
00170       private:
00171             static const nint32 DEFAULT_HEIGHT;
00172             
00173             NSkipNode<T> *m_head; // Head node;
00174             NSkipNode<T> **m_fix; // Update array;
00175             NSkipNode<T> *m_curl; // Current link
00176             nint32 m_maxh; // Max height;
00177             nint32 m_curh; // Current height;
00178             nuint64 m_size; // Size at level 0;
00179             
00180             // For the PRNG
00181             nint32 m_reset;
00182             nint32 m_bits;
00183             
00184             NSkipNode<T> *locate(const T &key) const;
00185             nint32 rlevel(void);
00186             void reset(void);
00187             
00188             NSkipNode<T> *findPtr(const T &key);
00189             
00190             NSkipList(const NSkipList &);
00191             NSkipList &operator=(const NSkipList &);
00192       
00193 };
00194 
00195 template <typename T>
00196 const nint32 NSkipList<T>::DEFAULT_HEIGHT = 24;
00197 
00198 
00199 template <typename T>
00200 NSkipList<T>::NSkipList(void) 
00201       : m_head(NULL),
00202       m_fix(NULL),
00203       m_curl(NULL),
00204       m_maxh(DEFAULT_HEIGHT),
00205       m_curh(0),
00206       m_size(0),
00207       m_reset(0),
00208       m_bits(0)
00209 {
00210       
00211       m_head = new NSkipNode<T>(m_maxh + 1);
00212       m_fix = new NSkipNode<T>*[m_maxh];
00213 }
00214 
00215 
00216 template <typename T>
00217 NSkipList<T>::NSkipList(nint32 max)
00218       : m_head(NULL),
00219       m_fix(NULL),
00220       m_curl(NULL),
00221       m_maxh(max),
00222       m_curh(0),
00223       m_size(0),
00224       m_reset(0),
00225       m_bits(0)
00226 {
00227       
00228       if (m_maxh < 16 || m_maxh > 32 ) {
00229             throw NException("Skiplist value must be between 16 and 32", 
00230                               NException::BASE,
00231                               NException::EX_OUT_OF_BOUNDS);
00232       }
00233       m_head = new NSkipNode<T>(m_maxh + 1);
00234       m_fix = new NSkipNode<T>*[m_maxh];
00235 }
00236 
00237 
00238 template <typename T>
00239 NSkipList<T>::~NSkipList(void) {
00240       clear();
00241       
00242       delete m_head;
00243       delete[] m_fix;
00244 }
00245 
00246 
00252 template <typename T>
00253 nint32 NSkipList<T>::rlevel(void) {
00254       nint32 h = 0; //random height;
00255       nint32 found = 0; 
00256       
00257       for (h = 0; found == 0; h++) {
00258             if (m_reset == 0) {
00259                   m_bits = nrand();
00260                   m_reset = sizeof(nint32) * CHAR_BIT - 1;
00261             }
00262             
00263             found = m_bits & 1;
00264             m_bits = m_bits >> 1;
00265             m_reset--;
00266       }
00267       
00268       if (h >= m_maxh) {
00269             h = m_maxh - 1;
00270       }
00271       
00272       return h;
00273 }
00274 
00275 
00276 template <typename T>
00277 bool NSkipList<T>::isEmpty(void) const {
00278       if (!m_head) {
00279             return true;
00280       }
00281       
00282       return false;
00283 }
00284 
00285 
00286 template <typename T>
00287 nint32 NSkipList<T>::getHeight(void) const {
00288       return m_curh;
00289 }
00290 
00291 
00296 template <typename T>
00297 NSkipNode<T> *NSkipList<T>::locate(const T &key) const {
00298       NSkipNode<T> *node = m_head;
00299       T tmp;
00300       
00301       for (int i = m_curh; i >= 0; i--) {
00302             while (node->next[i] != NULL) {
00303                   tmp = node->next[i]->data;
00304                   if (key <= tmp) {
00305                         break;
00306                   }
00307                   
00308                   node = node->next[i];
00309             }
00310             m_fix[i] = node;
00311       } 
00312       
00313       return node;
00314 }
00315 
00316 
00317 
00318 
00319 template <typename T>
00320 bool NSkipList<T>::contains(const T &key) const {
00321       NSkipNode<T> *node = m_head;
00322       T tmp;
00323       
00324       for (int i = m_curh; i >= 0; i--) {
00325             while (node->next[i] != NULL) {
00326                   tmp = node->next[i]->data;
00327                   if (key == tmp) {
00328                         return true;
00329                   }
00330                   
00331                   node = node->next[i];
00332             }
00333             m_fix[i] = node;
00334       } 
00335       
00336       return false;
00337 }
00338 
00339 
00340 template <typename T>
00341 void NSkipList<T>::reset(void) {
00342       m_curl = m_head->next[0];
00343 }
00344 
00345 
00346 template <typename T>
00347 bool NSkipList<T>::erase(const T &key) {
00348       NSkipNode<T> *node = NULL;
00349        
00350       node = findPtr(key);
00351       if (!node) {
00352             return false;
00353       }
00354       
00355       // Navigate through the nodes updating the "next" pointer of the 
00356       // immediatelly smaller node.
00357       for (int i = 0; i < m_curh; i++) {
00358             if (m_fix[i]->next[i] != node) {
00359                   break;
00360             }
00361             
00362             m_fix[i]->next[i] = node->next[i];
00363       }
00364       
00365       // Updates the current height
00366       while (m_curh > 0) {
00367             if (m_head && m_head->next && m_head->next[m_curh - 1] != NULL) {
00368                   break;
00369             }
00370             
00371             m_curh--;
00372       }
00373       
00374       m_size--;
00375       
00376       // Resets the "current" node pointer to match the current height.
00377       reset();    
00378       delete node;
00379 
00380       return true;
00381 }
00382 
00383 
00384 template <typename T>
00385 nuint64 NSkipList<T>::size(void) const {
00386       return count();
00387 }
00388 
00389 
00390 template <typename T>
00391 nuint64 NSkipList<T>::count(void) const {
00392       return m_size;
00393 }
00394 
00395 
00399 template <typename T>
00400 class NSkipList<T>::iterator {
00401       public:
00405             iterator(NSkipNode<T> *node)
00406                   : m_node(node)
00407             {}
00408             
00413             iterator(const iterator &other): m_node(NULL) {
00414                   m_node = other.m_node;
00415             }
00416             
00422             iterator &operator=(const iterator &rhs) {
00423                   m_node = rhs.m_node;
00424                   
00425                   return *this;
00426             }
00427             
00433             bool operator!=(const iterator &rhs) const {
00434                   if (!m_node || !rhs.m_node) { 
00435                         if (!m_node && !rhs.m_node) {
00436                               return false;
00437                         }
00438                         return true;
00439                   }
00440 
00441                   if (m_node->data != rhs.m_node->data) {
00442                         return true;
00443                   }
00444                   
00445                   return false;
00446             }
00447 
00453             bool operator==(const iterator &rhs) const {
00454                   if (!m_node || !rhs.m_node) { 
00455                         if (!m_node && !rhs.m_node) {
00456                               return true;
00457                         }
00458 
00459                         return false;
00460                   }
00461 
00462                   if (m_node->data == rhs.m_node->data) {
00463                         return true;
00464                   }
00465                   
00466                   return false;     
00467             }
00468             
00473             iterator operator++(int) {
00474                   iterator tmp(*this);
00475                   
00476                   inc();
00477                   return tmp;
00478             }
00479             
00484             const iterator &operator++(void) const {
00485                   iterator tmp(*this);
00486                   
00487                   m_node = m_node->next[0];
00488                   return *this;
00489             }
00490             
00495             const iterator operator++(int) const {
00496                   iterator tmp(*this);
00497                   
00498                   ++(*this);
00499                   return tmp;
00500             }
00501             
00506             T& operator*(void) {
00507                   return m_node->data;
00508             }
00509             
00514             const T& operator*(void) const {
00515                   return m_node->data;
00516             }
00517             
00522             T* operator->(void) {
00523                   return &m_node->data;
00524             }
00525             
00530             const T* operator->(void) const {
00531                   return &m_node->data;
00532             }
00533 
00534       private:
00535             mutable NSkipNode<T> *m_node;
00536             
00537             iterator inc(void) {
00538                   iterator tmp(*this);
00539                   
00540                   m_node = m_node->next[0];
00541                   return tmp;
00542             }
00543 };
00544 
00545 
00546 template <typename T>
00547 typename NSkipList<T>::iterator NSkipList<T>::begin(void) {
00548       if (m_head && m_head->next[0]) { 
00549             return typename NSkipList<T>::iterator(m_head->next[0]);
00550       }
00551       
00552       return typename NSkipList<T>::iterator(NULL);
00553 }
00554 
00555 
00556 template <typename T>
00557 NSKIPLIST_CONST NSkipList<T>::constBegin(void) const {
00558       if (m_head && m_head->next[0]) { 
00559             return typename NSkipList<T>::const_iterator(m_head->next[0]);
00560       }
00561       
00562       return typename NSkipList<T>::const_iterator(NULL);
00563 }
00564 
00565 
00566 template <typename T>
00567 typename NSkipList<T>::iterator NSkipList<T>::end(void) {
00568       return typename NSkipList<T>::iterator(NULL);
00569 }
00570 
00571 
00572 template <typename T>
00573 NSKIPLIST_CONST NSkipList<T>::constEnd(void) const {
00574       return typename NSkipList<T>::const_iterator(NULL);
00575 }
00576 
00577 
00578 template <typename T>
00579 NSkipNode<T> *NSkipList<T>::findPtr(const T &key) {
00580       NSkipNode<T> *node = m_head;
00581       T tmp;
00582             
00583       node = locate(key);
00584       if (!node) {
00585             return NULL;
00586       }
00587                   
00588       node = node->next[0];
00589       if (node && key == node->data) {
00590             return node;      
00591       }
00592       
00593       return NULL;
00594 }
00595 
00596 template <typename T>
00597 typename NSkipList<T>::iterator NSkipList<T>::find(const T &key) {
00598       return typename NSkipList<T>::iterator(find(key));
00599 }
00600 
00601 
00602 template <typename T>
00603 NSKIPLIST_CONST NSkipList<T>::find_const(const T &key) const {
00604       return typename NSkipList<T>::const_iterator(find(key));
00605 }
00606 
00607 
00608 template <typename T>
00609 typename NSkipList<T>::iterator NSkipList<T>::insert(const T &key) {
00610       nint32 height = 0;
00611       NSkipNode<T> *node = NULL;
00612             
00613       if (contains(key)) {
00614             return typename NSkipList<T>::iterator(NULL);
00615       }
00616       
00617       height = rlevel();
00618       node = new NSkipNode<T>(height, key);
00619       if (height > m_curh) {
00620             m_curh++;
00621             height = m_curh;
00622             m_fix[height] = m_head;
00623       }
00624       
00625       while (--height >= 0) {
00626             node->next[height] = m_fix[height]->next[height];
00627             m_fix[height]->next[height] = node;
00628       }
00629       
00630       m_size++;
00631       return typename NSkipList<T>::iterator(node);
00632 }
00633 
00634 
00635 template <typename T>
00636 void NSkipList<T>::clear(void) {
00637       NSkipNode<T> *node = NULL;
00638       NSkipNode<T> *save = NULL;
00639       
00640       if (!m_head || !m_head->next) {
00641             return;
00642       }
00643 
00644       node = m_head->next[0];
00645       while (node) {
00646             save = node->next[0];
00647             delete node;
00648             node = save;
00649             
00650       }
00651 }
00652 
00653 #endif // NSKIPLIST_HPP

Generated on Wed Mar 5 23:10:35 2008 for NemesisUtilitiesSystem by  doxygen 1.5.4