skiplist.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  4. #ifndef STORAGE_LEVELDB_DB_SKIPLIST_H_
  5. #define STORAGE_LEVELDB_DB_SKIPLIST_H_
  6. // Thread safety
  7. // -------------
  8. //
  9. // Writes require external synchronization, most likely a mutex.
  10. // Reads require a guarantee that the SkipList will not be destroyed
  11. // while the read is in progress. Apart from that, reads progress
  12. // without any internal locking or synchronization.
  13. //
  14. // Invariants:
  15. //
  16. // (1) Allocated nodes are never deleted until the SkipList is
  17. // destroyed. This is trivially guaranteed by the code since we
  18. // never delete any skip list nodes.
  19. //
  20. // (2) The contents of a Node except for the next/prev pointers are
  21. // immutable after the Node has been linked into the SkipList.
  22. // Only Insert() modifies the list, and it is careful to initialize
  23. // a node and use release-stores to publish the nodes in one or
  24. // more lists.
  25. //
  26. // ... prev vs. next pointer ordering ...
  27. #include <assert.h>
  28. #include <stdlib.h>
  29. #include "port/port.h"
  30. #include "util/arena.h"
  31. #include "util/random.h"
  32. namespace leveldb {
  33. class Arena;
  34. template<typename Key, class Comparator>
  35. class SkipList {
  36. private:
  37. struct Node;
  38. public:
  39. // Create a new SkipList object that will use "cmp" for comparing keys,
  40. // and will allocate memory using "*arena". Objects allocated in the arena
  41. // must remain allocated for the lifetime of the skiplist object.
  42. explicit SkipList(Comparator cmp, Arena* arena);
  43. // Insert key into the list.
  44. // REQUIRES: nothing that compares equal to key is currently in the list.
  45. void Insert(const Key& key);
  46. // Returns true iff an entry that compares equal to key is in the list.
  47. bool Contains(const Key& key) const;
  48. // Iteration over the contents of a skip list
  49. class Iterator {
  50. public:
  51. // Initialize an iterator over the specified list.
  52. // The returned iterator is not valid.
  53. explicit Iterator(const SkipList* list);
  54. // Returns true iff the iterator is positioned at a valid node.
  55. bool Valid() const;
  56. // Returns the key at the current position.
  57. // REQUIRES: Valid()
  58. const Key& key() const;
  59. // Advances to the next position.
  60. // REQUIRES: Valid()
  61. void Next();
  62. // Advances to the previous position.
  63. // REQUIRES: Valid()
  64. void Prev();
  65. // Advance to the first entry with a key >= target
  66. void Seek(const Key& target);
  67. // Position at the first entry in list.
  68. // Final state of iterator is Valid() iff list is not empty.
  69. void SeekToFirst();
  70. // Position at the last entry in list.
  71. // Final state of iterator is Valid() iff list is not empty.
  72. void SeekToLast();
  73. private:
  74. const SkipList* list_;
  75. Node* node_;
  76. // Intentionally copyable
  77. };
  78. private:
  79. enum { kMaxHeight = 12 };
  80. // Immutable after construction
  81. Comparator const compare_;
  82. Arena* const arena_; // Arena used for allocations of nodes
  83. Node* const head_;
  84. // Modified only by Insert(). Read racily by readers, but stale
  85. // values are ok.
  86. port::AtomicPointer max_height_; // Height of the entire list
  87. inline int GetMaxHeight() const {
  88. return static_cast<int>(
  89. reinterpret_cast<intptr_t>(max_height_.NoBarrier_Load()));
  90. }
  91. // Read/written only by Insert().
  92. Random rnd_;
  93. Node* NewNode(const Key& key, int height);
  94. int RandomHeight();
  95. bool Equal(const Key& a, const Key& b) const { return (compare_(a, b) == 0); }
  96. // Return true if key is greater than the data stored in "n"
  97. bool KeyIsAfterNode(const Key& key, Node* n) const;
  98. // Return the earliest node that comes at or after key.
  99. // Return NULL if there is no such node.
  100. //
  101. // If prev is non-NULL, fills prev[level] with pointer to previous
  102. // node at "level" for every level in [0..max_height_-1].
  103. Node* FindGreaterOrEqual(const Key& key, Node** prev) const;
  104. // Return the latest node with a key < key.
  105. // Return head_ if there is no such node.
  106. Node* FindLessThan(const Key& key) const;
  107. // Return the last node in the list.
  108. // Return head_ if list is empty.
  109. Node* FindLast() const;
  110. // No copying allowed
  111. SkipList(const SkipList&);
  112. void operator=(const SkipList&);
  113. };
  114. // Implementation details follow
  115. template<typename Key, class Comparator>
  116. struct SkipList<Key,Comparator>::Node {
  117. explicit Node(const Key& k) : key(k) { }
  118. Key const key;
  119. // Accessors/mutators for links. Wrapped in methods so we can
  120. // add the appropriate barriers as necessary.
  121. Node* Next(int n) {
  122. assert(n >= 0);
  123. // Use an 'acquire load' so that we observe a fully initialized
  124. // version of the returned Node.
  125. return reinterpret_cast<Node*>(next_[n].Acquire_Load());
  126. }
  127. void SetNext(int n, Node* x) {
  128. assert(n >= 0);
  129. // Use a 'release store' so that anybody who reads through this
  130. // pointer observes a fully initialized version of the inserted node.
  131. next_[n].Release_Store(x);
  132. }
  133. // No-barrier variants that can be safely used in a few locations.
  134. Node* NoBarrier_Next(int n) {
  135. assert(n >= 0);
  136. return reinterpret_cast<Node*>(next_[n].NoBarrier_Load());
  137. }
  138. void NoBarrier_SetNext(int n, Node* x) {
  139. assert(n >= 0);
  140. next_[n].NoBarrier_Store(x);
  141. }
  142. private:
  143. // Array of length equal to the node height. next_[0] is lowest level link.
  144. port::AtomicPointer next_[1];
  145. };
  146. template<typename Key, class Comparator>
  147. typename SkipList<Key,Comparator>::Node*
  148. SkipList<Key,Comparator>::NewNode(const Key& key, int height) {
  149. char* mem = arena_->AllocateAligned(
  150. sizeof(Node) + sizeof(port::AtomicPointer) * (height - 1));
  151. return new (mem) Node(key);
  152. }
  153. template<typename Key, class Comparator>
  154. inline SkipList<Key,Comparator>::Iterator::Iterator(const SkipList* list) {
  155. list_ = list;
  156. node_ = NULL;
  157. }
  158. template<typename Key, class Comparator>
  159. inline bool SkipList<Key,Comparator>::Iterator::Valid() const {
  160. return node_ != NULL;
  161. }
  162. template<typename Key, class Comparator>
  163. inline const Key& SkipList<Key,Comparator>::Iterator::key() const {
  164. assert(Valid());
  165. return node_->key;
  166. }
  167. template<typename Key, class Comparator>
  168. inline void SkipList<Key,Comparator>::Iterator::Next() {
  169. assert(Valid());
  170. node_ = node_->Next(0);
  171. }
  172. template<typename Key, class Comparator>
  173. inline void SkipList<Key,Comparator>::Iterator::Prev() {
  174. // Instead of using explicit "prev" links, we just search for the
  175. // last node that falls before key.
  176. assert(Valid());
  177. node_ = list_->FindLessThan(node_->key);
  178. if (node_ == list_->head_) {
  179. node_ = NULL;
  180. }
  181. }
  182. template<typename Key, class Comparator>
  183. inline void SkipList<Key,Comparator>::Iterator::Seek(const Key& target) {
  184. node_ = list_->FindGreaterOrEqual(target, NULL);
  185. }
  186. template<typename Key, class Comparator>
  187. inline void SkipList<Key,Comparator>::Iterator::SeekToFirst() {
  188. node_ = list_->head_->Next(0);
  189. }
  190. template<typename Key, class Comparator>
  191. inline void SkipList<Key,Comparator>::Iterator::SeekToLast() {
  192. node_ = list_->FindLast();
  193. if (node_ == list_->head_) {
  194. node_ = NULL;
  195. }
  196. }
  197. template<typename Key, class Comparator>
  198. int SkipList<Key,Comparator>::RandomHeight() {
  199. // Increase height with probability 1 in kBranching
  200. static const unsigned int kBranching = 4;
  201. int height = 1;
  202. while (height < kMaxHeight && ((rnd_.Next() % kBranching) == 0)) {
  203. height++;
  204. }
  205. assert(height > 0);
  206. assert(height <= kMaxHeight);
  207. return height;
  208. }
  209. template<typename Key, class Comparator>
  210. bool SkipList<Key,Comparator>::KeyIsAfterNode(const Key& key, Node* n) const {
  211. // NULL n is considered infinite
  212. return (n != NULL) && (compare_(n->key, key) < 0);
  213. }
  214. template<typename Key, class Comparator>
  215. typename SkipList<Key,Comparator>::Node* SkipList<Key,Comparator>::FindGreaterOrEqual(const Key& key, Node** prev)
  216. const {
  217. Node* x = head_;
  218. int level = GetMaxHeight() - 1;
  219. while (true) {
  220. Node* next = x->Next(level);
  221. if (KeyIsAfterNode(key, next)) {
  222. // Keep searching in this list
  223. x = next;
  224. } else {
  225. if (prev != NULL) prev[level] = x;
  226. if (level == 0) {
  227. return next;
  228. } else {
  229. // Switch to next list
  230. level--;
  231. }
  232. }
  233. }
  234. }
  235. template<typename Key, class Comparator>
  236. typename SkipList<Key,Comparator>::Node*
  237. SkipList<Key,Comparator>::FindLessThan(const Key& key) const {
  238. Node* x = head_;
  239. int level = GetMaxHeight() - 1;
  240. while (true) {
  241. assert(x == head_ || compare_(x->key, key) < 0);
  242. Node* next = x->Next(level);
  243. if (next == NULL || compare_(next->key, key) >= 0) {
  244. if (level == 0) {
  245. return x;
  246. } else {
  247. // Switch to next list
  248. level--;
  249. }
  250. } else {
  251. x = next;
  252. }
  253. }
  254. }
  255. template<typename Key, class Comparator>
  256. typename SkipList<Key,Comparator>::Node* SkipList<Key,Comparator>::FindLast()
  257. const {
  258. Node* x = head_;
  259. int level = GetMaxHeight() - 1;
  260. while (true) {
  261. Node* next = x->Next(level);
  262. if (next == NULL) {
  263. if (level == 0) {
  264. return x;
  265. } else {
  266. // Switch to next list
  267. level--;
  268. }
  269. } else {
  270. x = next;
  271. }
  272. }
  273. }
  274. template<typename Key, class Comparator>
  275. SkipList<Key,Comparator>::SkipList(Comparator cmp, Arena* arena)
  276. : compare_(cmp),
  277. arena_(arena),
  278. head_(NewNode(0 /* any key will do */, kMaxHeight)),
  279. max_height_(reinterpret_cast<void*>(1)),
  280. rnd_(0xdeadbeef) {
  281. for (int i = 0; i < kMaxHeight; i++) {
  282. head_->SetNext(i, NULL);
  283. }
  284. }
  285. template<typename Key, class Comparator>
  286. void SkipList<Key,Comparator>::Insert(const Key& key) {
  287. // TODO(opt): We can use a barrier-free variant of FindGreaterOrEqual()
  288. // here since Insert() is externally synchronized.
  289. Node* prev[kMaxHeight];
  290. Node* x = FindGreaterOrEqual(key, prev);
  291. // Our data structure does not allow duplicate insertion
  292. assert(x == NULL || !Equal(key, x->key));
  293. int height = RandomHeight();
  294. if (height > GetMaxHeight()) {
  295. for (int i = GetMaxHeight(); i < height; i++) {
  296. prev[i] = head_;
  297. }
  298. //fprintf(stderr, "Change height from %d to %d\n", max_height_, height);
  299. // It is ok to mutate max_height_ without any synchronization
  300. // with concurrent readers. A concurrent reader that observes
  301. // the new value of max_height_ will see either the old value of
  302. // new level pointers from head_ (NULL), or a new value set in
  303. // the loop below. In the former case the reader will
  304. // immediately drop to the next level since NULL sorts after all
  305. // keys. In the latter case the reader will use the new node.
  306. max_height_.NoBarrier_Store(reinterpret_cast<void*>(height));
  307. }
  308. x = NewNode(key, height);
  309. for (int i = 0; i < height; i++) {
  310. // NoBarrier_SetNext() suffices since we will add a barrier when
  311. // we publish a pointer to "x" in prev[i].
  312. x->NoBarrier_SetNext(i, prev[i]->NoBarrier_Next(i));
  313. prev[i]->SetNext(i, x);
  314. }
  315. }
  316. template<typename Key, class Comparator>
  317. bool SkipList<Key,Comparator>::Contains(const Key& key) const {
  318. Node* x = FindGreaterOrEqual(key, NULL);
  319. if (x != NULL && Equal(key, x->key)) {
  320. return true;
  321. } else {
  322. return false;
  323. }
  324. }
  325. } // namespace leveldb
  326. #endif // STORAGE_LEVELDB_DB_SKIPLIST_H_