Phoenix
Object-oriented orthogonally persistent operating system
|
00001 /* 00002 * /phoenix/include/common/RBTree.h 00003 * 00004 * This file is a part of Phoenix operating system. 00005 * Copyright (c) 2011-2012, Artyom Lebedev <artyom.lebedev@gmail.com> 00006 * All rights reserved. 00007 * See COPYING file for copyright details. 00008 */ 00009 00014 #ifndef RBTREE_H_ 00015 #define RBTREE_H_ 00016 00018 class RBTreeBase { 00019 public: 00026 bool Validate(); 00027 00028 protected: 00030 class EntryBase { 00031 protected: 00032 friend class RBTreeBase; 00033 00034 u8 isRed:1, 00035 isWired:1; 00036 EntryBase *parent, *child[2]; 00037 00038 EntryBase() { isWired = false; } 00039 }; 00040 00041 RBTreeBase(); 00042 00050 virtual int Compare(EntryBase *e1, EntryBase *e2) = 0; 00051 00059 virtual int Compare(EntryBase *e, void *key) = 0; 00060 00068 EntryBase *InsertNode(EntryBase *node); 00069 00075 EntryBase *GetNextNode(EntryBase *node = 0); 00076 00082 EntryBase *Lookup(void *key); 00083 00088 void Delete(EntryBase *entry); 00089 00094 EntryBase *Lowest(); 00095 00100 EntryBase *Highest(); 00101 00102 private: 00104 EntryBase *_root; 00106 size_t _nodesCount; 00108 unsigned _generation; 00109 00118 void _RebalanceInsertion(EntryBase *node); 00119 00123 void _RebalanceDeletion(EntryBase *node); 00124 00131 inline void _Rotate(EntryBase *node, int dir) { 00132 ASSERT(dir == 0 || dir == 1); 00133 EntryBase *x = node->child[dir]; 00134 ASSERT(x); 00135 x->parent = node->parent; 00136 if (node->parent) { 00137 if (node->parent->child[0] == node) { 00138 node->parent->child[0] = x; 00139 } else { 00140 ASSERT(node->parent->child[1] == node); 00141 node->parent->child[1] = x; 00142 } 00143 } else { 00144 ASSERT(_root == node); 00145 _root = x; 00146 } 00147 00148 node->child[dir] = x->child[!dir]; 00149 if (node->child[dir]) { 00150 node->child[dir]->parent = node; 00151 } 00152 00153 x->child[!dir] = node; 00154 node->parent = x; 00155 } 00156 00162 inline void _CheckRebalanceInsertion(EntryBase *node) { 00163 ASSERT(node->isRed); 00164 if (node->parent && node->parent->isRed && node->parent->parent) { 00165 _RebalanceInsertion(node); 00166 } 00167 } 00168 }; 00169 00206 template <class T, int (T::*Comparator)(T &obj), 00207 typename key_t, int (T::*KeyComparator)(key_t &key)> 00208 class RBTree : public RBTreeBase { 00209 public: 00210 class Entry : public EntryBase { 00211 protected: 00212 friend class RBTree; 00213 00214 T *obj; 00215 }; 00216 00217 inline RBTree() : RBTreeBase() { } 00218 00219 virtual int Compare(EntryBase *e1, EntryBase *e2) 00220 { 00221 return (static_cast<Entry *>(e1)->obj->*Comparator)(*static_cast<Entry *>(e2)->obj); 00222 } 00223 00224 virtual int Compare(EntryBase *e, void *key) 00225 { 00226 if (!KeyComparator) { 00227 FAULT("Key comparator not provided"); 00228 } 00229 return (static_cast<Entry *>(e)->obj->*KeyComparator)(*static_cast<key_t *>(key)); 00230 } 00231 00241 inline T *InsertProbe(T *obj, Entry *e) 00242 { 00243 e->obj = obj; 00244 return static_cast<Entry *>(InsertNode(e))->obj; 00245 } 00246 00256 inline T *Insert(T *obj, Entry *e) 00257 { 00258 e->obj = obj; 00259 if (static_cast<Entry *>(InsertNode(e)) != e) { 00260 return 0; 00261 } 00262 return obj; 00263 } 00264 00270 inline T *Lookup(key_t &key) 00271 { 00272 EntryBase *e = RBTreeBase::Lookup(&key); 00273 if (!e) { 00274 return 0; 00275 } 00276 return static_cast<Entry *>(e)->obj; 00277 } 00278 00283 inline void Delete(Entry *e) 00284 { 00285 RBTreeBase::Delete(static_cast<EntryBase *>(e)); 00286 } 00287 00293 inline T *Delete(key_t &key) 00294 { 00295 EntryBase *e = RBTreeBase::Lookup(&key); 00296 if (!e) { 00297 return 0; 00298 } 00299 RBTreeBase::Delete(e); 00300 return static_cast<Entry *>(e)->obj; 00301 } 00302 00307 inline T *Lowest() { 00308 EntryBase *e = RBTreeBase::Lowest(); 00309 if (!e) { 00310 return 0; 00311 } 00312 return static_cast<Entry *>(e)->obj; 00313 } 00314 00319 inline T *Highest() { 00320 EntryBase *e = RBTreeBase::Highest(); 00321 if (!e) { 00322 return 0; 00323 } 00324 return static_cast<Entry *>(e)->obj; 00325 } 00326 00327 /* Iteration interface. */ 00328 00329 class Iterator { 00330 public: 00331 inline Iterator(RBTree &tree, bool isStart) : 00332 _tree(tree) 00333 { 00334 if (isStart) { 00335 e = static_cast<Entry *>(_tree.GetNextNode()); 00336 } else { 00337 e = 0; 00338 } 00339 } 00340 00341 inline bool operator !=(Iterator &iter) { return e != iter.e; } 00342 00343 inline void operator ++() { 00344 if (e) { 00345 e = static_cast<Entry *>(_tree.GetNextNode(e)); 00346 } 00347 } 00348 00349 inline T &operator *() { return *e->obj; } 00350 00351 private: 00352 RBTree &_tree; 00353 Entry *e; 00354 }; 00355 00356 inline Iterator begin() { return Iterator(*this, true); } 00357 inline Iterator end() { return Iterator(*this, false); } 00358 }; 00359 00360 template <class T, int (T::*Comparator)(T &obj), 00361 typename key_t, int (T::*KeyComparator)(key_t &key)> 00362 static inline typename RBTree<T, Comparator, key_t, KeyComparator>::Iterator 00363 begin(RBTree<T, Comparator, key_t, KeyComparator> &tree) 00364 { 00365 return tree.begin(); 00366 } 00367 00368 template <class T, int (T::*Comparator)(T &obj), 00369 typename key_t, int (T::*KeyComparator)(key_t &key)> 00370 static inline typename RBTree<T, Comparator, key_t, KeyComparator>::Iterator 00371 end(RBTree<T, Comparator, key_t, KeyComparator> &tree) 00372 { 00373 return tree.end(); 00374 } 00375 00376 #endif /* RBTREE_H_ */