Set.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #pragma once
  24. #include "Iterator.h"
  25. #include <cstdlib>
  26. #include <new>
  27. // Based on http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_skip.aspx
  28. /// Set template class using a skip list
  29. template <class T> class Set
  30. {
  31. public:
  32. /// Set node
  33. struct Node : public SkipListNodeBase
  34. {
  35. /// Key
  36. T key_;
  37. /// Return next node on a specific height
  38. Node* GetNext(unsigned height) const
  39. {
  40. if (!height)
  41. return static_cast<Node*>(next_);
  42. else
  43. return static_cast<Node*>(levels_[height - 1]);
  44. }
  45. /// Return previous node
  46. Node* GetPrev() { return static_cast<Node*>(prev_); }
  47. };
  48. /// Set node iterator
  49. class Iterator : public ListIteratorBase
  50. {
  51. public:
  52. explicit Iterator(Node* ptr) :
  53. ptr_(ptr)
  54. {
  55. }
  56. /// Point to the key
  57. const T* operator -> () const { return &(static_cast<Node*>(ptr_))->key_; }
  58. /// Dereference the key
  59. const T& operator * () const { return (static_cast<Node*>(ptr_))->key_; }
  60. };
  61. /// Set node const iterator
  62. class ConstIterator : public ListIteratorBase
  63. {
  64. public:
  65. explicit ConstIterator(Node* ptr) :
  66. ptr_(ptr)
  67. {
  68. }
  69. /// Point to the key
  70. const T* operator -> () const { return &(static_cast<Node*>(ptr_))->key_; }
  71. /// Dereference the key
  72. const T& operator * () const { return (static_cast<Node*>(ptr_))->key_; }
  73. };
  74. /// Construct empty
  75. Set(unsigned maxHeight = MAX_HEIGHT) :
  76. maxHeight_(maxHeight < MAX_HEIGHT ? maxHeight : MAX_HEIGHT),
  77. height_(0),
  78. size_(0),
  79. bitsLeft_(0)
  80. {
  81. // Allocate the head and tail nodes and zero the next pointers
  82. head_ = AllocateNode(maxHeight_);
  83. tail_ = AllocateNode(maxHeight_);
  84. for (unsigned i = 0; i < maxHeight_; ++i)
  85. {
  86. head_->SetNext(i, tail_);
  87. tail_->SetNext(i, 0);
  88. }
  89. // Allocate the fixup pointers
  90. fix_ = new Node*[maxHeight_];
  91. }
  92. /// Construct from another set
  93. Set(const Set<T>& set) :
  94. maxHeight_(set.maxHeight_),
  95. height_(0),
  96. size_(0),
  97. bitsLeft_(0)
  98. {
  99. // Allocate the head and tail nodes and zero the next pointers
  100. head_ = AllocateNode(maxHeight_);
  101. tail_ = AllocateNode(maxHeight_);
  102. for (unsigned i = 0; i < maxHeight_; ++i)
  103. {
  104. head_->SetNext(i, tail_);
  105. tail_->SetNext(i, 0);
  106. }
  107. // Allocate the fixup pointers
  108. fix_ = new Node*[maxHeight_];
  109. // Then assign the another set
  110. *this = set;
  111. }
  112. /// Destruct
  113. ~Set()
  114. {
  115. Clear();
  116. DeleteNode(head_);
  117. DeleteNode(tail_);
  118. delete[] fix_;
  119. }
  120. /// Assign from another set
  121. Set& operator = (const Set<T>& rhs)
  122. {
  123. Clear();
  124. // Insert the nodes with same heights
  125. for (Node* i = rhs.head_->next_[0]; i; i = i->next_[0])
  126. InsertNode(i->key_, i->height_);
  127. return *this;
  128. }
  129. /// Add-assign a key
  130. Set& operator += (const T& rhs)
  131. {
  132. Insert(rhs);
  133. return *this;
  134. }
  135. /// Add-assign a set
  136. Set& operator += (const Set<T>& rhs)
  137. {
  138. for (Iterator i = rhs.Begin(); i != rhs.End(); ++i)
  139. Insert(*i);
  140. return *this;
  141. }
  142. /// Test for equality with another set
  143. bool operator == (const Set<T>& rhs) const
  144. {
  145. if (rhs.size_ != size_)
  146. return false;
  147. Iterator i = Begin();
  148. Iterator j = rhs.Begin();
  149. while (i != End())
  150. {
  151. if (*i != *j)
  152. return false;
  153. ++i;
  154. ++j;
  155. }
  156. return true;
  157. }
  158. /// Test for inequality with another set
  159. bool operator != (const Set<T>& rhs) const
  160. {
  161. if (rhs.size_ != size_)
  162. return true;
  163. Iterator i = Begin();
  164. Iterator j = rhs.Begin();
  165. while (i != End())
  166. {
  167. if (*i != *j)
  168. return true;
  169. ++i;
  170. ++j;
  171. }
  172. return false;
  173. }
  174. /// Insert into the set. Return true if did not exist already
  175. bool Insert(const T& key)
  176. {
  177. return InsertNode(key, 0);
  178. }
  179. /// Insert a range by iterators
  180. void Insert(const Iterator& start, const Iterator& end)
  181. {
  182. Iterator it = start;
  183. while ((it) && (it != end))
  184. {
  185. Iterator current = it++;
  186. Insert(*current);
  187. // Break if the iterator got stuck
  188. if (it == current)
  189. break;
  190. }
  191. }
  192. /// Erase a key from the set. Return true if was found and erased
  193. bool Erase(const T& key)
  194. {
  195. Node* i = head_;
  196. for (unsigned j = height_ - 1; j < MAX_HEIGHT; --j)
  197. {
  198. for (;;)
  199. {
  200. Node* next = i->GetNext(j);
  201. if ((next) && (next != tail_) && (key > next->key_))
  202. i = next;
  203. else
  204. break;
  205. }
  206. fix_[j] = i;
  207. }
  208. // Check if key does not exist
  209. Node* toRemove = i->GetNext(0);
  210. if ((!toRemove) || (toRemove == tail_) || (toRemove->key_ != key))
  211. return false;
  212. // Fix the previous link. However, do not set the head node as a previous link
  213. Node* prev = toRemove->GetPrev();
  214. Node* next = toRemove->GetNext(0);
  215. if (next)
  216. next->SetPrev(prev != head_ ? prev : 0);
  217. // Fix the next links
  218. for (unsigned j = 0; j < height_; ++j)
  219. {
  220. Node* fixNext = fix_[j]->GetNext(j);
  221. if (fixNext)
  222. fix_[j]->SetNext(j, fixNext->GetNext(j));
  223. }
  224. // Check if height should be changed
  225. while (height_ > 0)
  226. {
  227. if (head_->GetNext(height_ - 1))
  228. break;
  229. head_->SetNext(--height_, 0);
  230. }
  231. DeleteNode(toRemove);
  232. --size_;
  233. return true;
  234. }
  235. /// Erase by an iterator. Return an iterator to the next element
  236. Iterator Erase(const Iterator& it)
  237. {
  238. if (it)
  239. {
  240. Iterator current = it++;
  241. Erase(*current);
  242. }
  243. return it;
  244. }
  245. /// Erase by a range of iterators. Return the end iterator
  246. Iterator Erase(const Iterator& start, const Iterator& end)
  247. {
  248. Iterator it = start;
  249. while (it != end)
  250. {
  251. Iterator current = it++;
  252. // Break if the iterator got stuck
  253. if (it == current)
  254. break;
  255. Erase(*current);
  256. }
  257. return it;
  258. }
  259. /// Clear the set
  260. void Clear()
  261. {
  262. // Let the head and tails node remain, but reset the next pointers
  263. Node* node = head_->GetNext(0);
  264. for (unsigned i = 0; i < maxHeight_; ++i)
  265. {
  266. head_->SetNext(i, tail_);
  267. tail_->SetNext(i, 0);
  268. tail_->SetPrev(0);
  269. }
  270. // Then remove all the key nodes
  271. while (node != tail_)
  272. {
  273. Node* current = node;
  274. node = node->GetNext(0);
  275. DeleteNode(current);
  276. }
  277. height_ = 0;
  278. size_ = 0;
  279. }
  280. /// Return iterator to the node with key, or null iterator if not found
  281. Iterator Find(const T& key) { return Iterator(FindNode(key)); }
  282. /// Return const iterator to the node with key, or null iterator if not found
  283. ConstIterator Find(const T& key) const { return ConstIterator(FindNode(key)); }
  284. /// Return iterator to the first actual node
  285. Iterator Begin() { return Iterator(head_->next_[0]); }
  286. /// Return iterator to the first actual node
  287. ConstIterator Begin() const { return ConstIterator(head_->next_[0]); }
  288. /// Return iterator to the end
  289. Iterator End() { return Iterator(tail_); }
  290. /// Return iterator to the end
  291. ConstIterator End() const { return ConstIterator(tail_); }
  292. /// Return whether contains a key
  293. bool Contains(const T& key) const { return FindNode(key) != 0; }
  294. /// Return number of keys
  295. unsigned Size() const { return size_; }
  296. /// Return current height
  297. unsigned Height() const { return height_; }
  298. /// Return whether set is empty
  299. bool Empty() const { return size_ == 0; }
  300. static const unsigned MAX_HEIGHT = 15;
  301. private:
  302. /// Find a key from the set. Return null if not found
  303. Node* FindNode(const T& key) const
  304. {
  305. Node* i = head_;
  306. for (unsigned j = height_ - 1; j < MAX_HEIGHT; --j)
  307. {
  308. for (;;)
  309. {
  310. Node* next = i->GetNext(j);
  311. if ((next) && (next != tail_) && (key > next->key_))
  312. i = next;
  313. else
  314. break;
  315. }
  316. }
  317. Node* next = i->GetNext(0);
  318. if ((next) && (next != tail_) && (next->key_ == key))
  319. return next;
  320. else
  321. return 0;
  322. }
  323. /// Insert into the set with a specific height. Zero height will randomize
  324. bool InsertNode(const T& key, unsigned height)
  325. {
  326. Node* i = head_;
  327. for (unsigned j = height_ - 1; j < MAX_HEIGHT; --j)
  328. {
  329. for (;;)
  330. {
  331. Node* next = i->GetNext(j);
  332. if ((next) && (next != tail_) && (key > next->key_))
  333. i = next;
  334. else
  335. break;
  336. }
  337. fix_[j] = i;
  338. }
  339. // Check if key already exists
  340. Node* next = i->GetNext(0);
  341. if ((next) && (next != tail_) && (next->key_ == key))
  342. return false;
  343. // Create new node, assign height and key
  344. if (!height)
  345. height = GetHeight();
  346. Node* newNode = AllocateNode(height);
  347. newNode->key_ = key;
  348. // Fix the previous link, however do not set the head node as previous
  349. if (i != head_)
  350. newNode->SetPrev(i);
  351. if (next)
  352. next->SetPrev(newNode);
  353. while (newNode->height_ > height_)
  354. fix_[height_++] = head_;
  355. for (unsigned h = 0; h < newNode->height_; ++h)
  356. {
  357. newNode->SetNext(h, fix_[h]->GetNext(h));
  358. fix_[h]->SetNext(h, newNode);
  359. }
  360. ++size_;
  361. return true;
  362. }
  363. /// Generate a random height for a new node
  364. unsigned GetHeight()
  365. {
  366. unsigned height = 1;
  367. while ((height < maxHeight_) && (GetBit()))
  368. ++height;
  369. return height;
  370. }
  371. /// Return a random true/false result
  372. bool GetBit()
  373. {
  374. if (!bitsLeft_)
  375. {
  376. random_ = rand();
  377. bitsLeft_ = 15;
  378. }
  379. bool ret = (random_ & 1) != 0;
  380. random_ >>= 1;
  381. --bitsLeft_;
  382. return ret;
  383. }
  384. /// Allocate a node and its next pointers
  385. Node* AllocateNode(unsigned height)
  386. {
  387. unsigned char* block = new unsigned char[sizeof(Node) + (height - 1) * sizeof(Node*)];
  388. Node* newNode = reinterpret_cast<Node*>(block);
  389. // Construct the key with placement new and set the next pointers' address
  390. new(&newNode->key_) T();
  391. newNode->height_ = height;
  392. if (height > 1)
  393. newNode->levels_ = reinterpret_cast<SkipListNodeBase**>(block + sizeof(Node));
  394. else
  395. newNode->levels_ = 0;
  396. return newNode;
  397. }
  398. /// Delete a node
  399. void DeleteNode(Node* node)
  400. {
  401. // Destruct the key, then delete the memory block
  402. (&node->key_)->~T();
  403. delete[] reinterpret_cast<unsigned char*>(node);
  404. }
  405. /// Head node pointer
  406. Node* head_;
  407. /// Tail node pointer
  408. Node* tail_;
  409. /// Fixup pointers for insert & erase
  410. Node** fix_;
  411. /// Maximum height
  412. unsigned maxHeight_;
  413. /// Current height
  414. unsigned height_;
  415. /// Number of keys
  416. unsigned size_;
  417. /// Random bits
  418. unsigned short random_;
  419. /// Random bits remaining
  420. unsigned short bitsLeft_;
  421. };