1 #ifndef __SKIPLIST_H__
2 #define __SKIPLIST_H__
3 
4 // This file (C) 2004-2009 Steven Boswell.  All rights reserved.
5 // Released to the public under the GNU General Public License v2.
6 // See the file COPYING for more information.
7 
8 /* A skip list is a sorted data structure with probabilistic balancing
9    that performs the same functions as balanced-binary-tree sorts of
10    data structures, but skip lists have lots of unusual avenues for
11    optimizations not available to binary trees. */
12 
13 #include "config.h"
14 #include <assert.h>
15 #include <stdlib.h>
16 #include <new>
17 #include "mjpeg_types.h"
18 #include "Status_t.h"
19 #include "Allocator.hh"
20 
21 
22 
23 // Define this to compile in code to double-check and debug the skip
24 // list.
25 #ifndef NDEBUG
26 //	#define DEBUG_SKIPLIST
27 #endif // NDEBUG
28 
29 
30 
31 // The skip list.  Parameterized by the class of the sorting key, the
32 // class of the contained value, the method for extracting the key from
33 // the value, the method for comparing keys, the number of forward pointers
34 // in the header, and the type of allocator to use for skip-list nodes.
35 template <class KEY, class VALUE, class KEYFN, class PRED,
36 	int HC = 10, class ALLOC = Allocator<HC> >
37 class SkipList
38 {
39 private:
40 	// The type of a node in the skip list.
41 	struct Node
42 	{
43 		VALUE m_oValue;
44 			// The data held by this node.
45 		#ifdef DEBUG_SKIPLIST
46 		int32_t m_nLevel;
47 		#endif // DEBUG_SKIPLIST
48 			// The number of forward pointers in this node.
49 		Node *m_pBackward;
50 			// The node before this one.
51 		Node *m_apForward[1];
52 			// The nodes after this one, at all the levels we exist.
53 	};
54 
55 	SkipList (const SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther);
56 	const SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &operator =
57 			(const SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther);
58 		// Disallow copying and assignment.
59 
60  	enum { HEADERCHUNK = HC };
61  		// The number of forward pointers in the header.
62  		// Will give good sorting for up to e^HC items.
63 
64 public:
65 	typedef ALLOC Allocator_t;
66 		// The type of node allocator to use.
67 
68 	static Allocator_t sm_oNodeAllocator;
69 		// The default node allocator.
70 
71 	// A structure that contains all of our initialization parameters.
72 	struct InitParams
73 	{
74 	public:
75 		uint32_t m_nRandSeed;
76 			// The skip list's random number seed.
77 
78 		bool m_bAllocateInternalNodesFromAllocator;
79 			// True if the skip list's internal nodes (i.e. the header
80 			// and search-fingers) should be allocated from the allocator.
81 			// False if they should be allocated from system memory.
82 			//
83 			// Since these nodes live for the lifetime of the skip-list,
84 			// allocating them from the allocator prevents the allocator
85 			// from being able to purge itself.
86 
InitParamsSkipList::InitParams87 		InitParams() : m_nRandSeed (rand()),
88 				m_bAllocateInternalNodesFromAllocator (false) {}
89 			// Default constructor.
90 			// Gets the random seed from the system.
91 
InitParamsSkipList::InitParams92 		InitParams (uint32_t a_nRandSeed,
93 				bool a_bAllocateInternalNodesFromAllocator)
94 			: m_nRandSeed (a_nRandSeed),
95 				m_bAllocateInternalNodesFromAllocator
96 					(a_bAllocateInternalNodesFromAllocator) {}
97 			// Initializing constructor.
98 	};
99 
100 	SkipList (const PRED &a_rPred = PRED(),
101 			Allocator_t &a_rAlloc = sm_oNodeAllocator);
102 		// Default constructor.  Must be followed by Init().
103 
104 	SkipList (Status_t &a_reStatus, bool a_bAllowDuplicates,
105 			const InitParams &a_rInitParams, const PRED &a_rPred = PRED(),
106 			Allocator_t &a_rAlloc = sm_oNodeAllocator);
107 		// Constructor.  Specify whether or not duplicates are allowed,
108 		// and provide a random number seed.
109 
110 	void Init (Status_t &a_reStatus, bool a_bAllowDuplicates,
111 			const InitParams &a_rInitParams);
112 		// Construction method.  Specify whether or not duplicates are
113 		// allowed, and provide a random number seed.
114 
115 	virtual ~SkipList (void);
116 		// Destructor.
117 
118 #ifdef DEBUG_SKIPLIST
119 
120 	void Invariant (void) const;
121 		// Thoroughly analyze the skip list for structural integrity.
122 
123 	void SetDebug (bool a_bDebug);
124 		// Set whether to run the skip-list invariant before and after
125 		// methods.
126 
127 #endif // DEBUG_SKIPLIST
128 
129 	//
130 	// Iterator classes.
131 	//
132 
133 	class Iterator;
134 	class ConstIterator;
135 	friend class ConstIterator;
136 	class ConstIterator
137 	{
138 		protected:
139 			friend class SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>;
140 				// Let SkipList access m_pNode.
141 			Node *m_pNode;
142 				// The node we represent.
143 		public:
ConstIterator()144 			ConstIterator() { m_pNode = NULL; }
ConstIterator(Node * a_pNode)145 			ConstIterator (Node *a_pNode) : m_pNode (a_pNode) {}
ConstIterator(const Iterator & a_rOther)146 			ConstIterator (const Iterator &a_rOther)
147 				: m_pNode (a_rOther.m_pNode) {}
operator *() const148 			const VALUE &operator*() const {return m_pNode->m_oValue; }
operator ++()149 			ConstIterator& operator++()
150 				{ m_pNode = m_pNode->m_apForward[0];
151 					return *this; }
operator ++(int)152 			ConstIterator operator++(int) { ConstIterator oTmp = *this;
153 				++*this; return oTmp; }
operator --()154 			ConstIterator& operator--()
155 				{ m_pNode = m_pNode->m_pBackward;
156 					return *this; }
operator --(int)157 			ConstIterator operator--(int) { ConstIterator oTmp = *this;
158 				--*this; return oTmp; }
operator ==(const ConstIterator & a_rOther) const159 			bool operator== (const ConstIterator &a_rOther) const
160 				{ return (m_pNode == a_rOther.m_pNode) ? true : false; }
operator !=(const ConstIterator & a_rOther) const161 			bool operator!= (const ConstIterator &a_rOther) const
162 				{ return (m_pNode != a_rOther.m_pNode) ? true : false; }
163 	};
164 	friend class Iterator;
165 	class Iterator : public ConstIterator
166 	{
167 		private:
168 			typedef ConstIterator BaseClass;
169 				// Keep track of who our base class is.
170 
171 		public:
Iterator()172 			Iterator() : ConstIterator() {}
Iterator(Node * a_pNode)173 			Iterator (Node *a_pNode) : ConstIterator (a_pNode) {}
operator *()174 			VALUE &operator*() {return BaseClass::m_pNode->m_oValue; }
operator ++()175 			Iterator& operator++() { BaseClass::m_pNode
176 				= BaseClass::m_pNode->m_apForward[0]; return *this; }
operator ++(int)177 			Iterator operator++(int) { Iterator oTmp = *this; ++*this;
178 				return oTmp; }
operator --()179 			Iterator& operator--() { BaseClass::m_pNode
180 				= BaseClass::m_pNode->m_pBackward; return *this; }
operator --(int)181 			Iterator operator--(int) { Iterator oTmp = *this; --*this;
182 				return oTmp; }
operator ==(const ConstIterator & a_rOther) const183 			bool operator== (const ConstIterator &a_rOther) const
184 				{ return (((BaseClass&)(*this)) == a_rOther); }
operator !=(const ConstIterator & a_rOther) const185 			bool operator!= (const ConstIterator &a_rOther) const
186 				{ return (((BaseClass&)(*this)) != a_rOther); }
187 	};
188 
189 	//
190 	// Skip list methods.
191 	//
192 
Begin(void)193 	Iterator Begin (void)
194 			{ return Iterator (m_pHeader->m_apForward[0]); }
195 		// Return an iterator to the beginning of the list.
196 
Begin(void) const197 	ConstIterator Begin (void) const
198 			{ return ConstIterator (m_pHeader->m_apForward[0]); }
199 		// Return an iterator to the beginning of the list.
200 
End(void)201 	Iterator End (void) { return Iterator (m_pHeader); }
202 		// Return an iterator to the end of the list.
203 
End(void) const204 	ConstIterator End (void) const { return ConstIterator (m_pHeader); }
205 		// Return an iterator to the end of the list.
206 
Size(void) const207 	uint32_t Size (void) const { return m_nItems; }
208 		// Return the number of items in the list.
209 		// (May be called on a default-constructed object, making it
210 		// possible for default-constructed subclasses/owners to destroy
211 		// themselves safely.)
212 
Empty(void) const213 	bool Empty (void) const { return (m_nItems == 0) ? true : false; }
214 		// Return whether the list is empty.
215 
216 	// A structure used to return the result of an insertion.
217 	struct InsertResult
218 	{
219 		Iterator m_itPosition;
220 			// Where the item was inserted, or where the duplicate was
221 			// found.
222 
223 		bool m_bInserted;
224 			// true if the item was inserted into the list.
225 	};
226 
227 	InsertResult Insert (Status_t &a_reStatus, const VALUE &a_rValue);
228 		// Insert an item into the list.
229 
230 	Iterator Insert (Status_t &a_reStatus, Iterator a_oPosition,
231 			const VALUE &a_rValue);
232 		// Insert an item into the list, at this exact location, if it's
233 		// safe.  Returns where it was really inserted.
234 
235 	void Insert (Status_t &a_reStatus, ConstIterator a_oFirst,
236 			ConstIterator a_oLast);
237 		// Insert a range of items from another skip-list.
238 
239 	Iterator Erase (Iterator a_oHere);
240 		// Erase the item here.  Return the item following the one
241 		// removed.
242 
243 	Iterator Erase (Iterator a_oFirst, Iterator a_oLast);
244 		// Erase a range of items in this list.  Return the item
245 		// following the last one removed.
246 
247 	void Clear (void);
248 		// Empty the list.
249 
Purge(void)250 	void Purge (void) { }
251 		// Purge all internally-allocated memory.
252 		// Not implemented for SkipList -- this is only here to preserve
253 		// interface compatibility with Vector<>.
254 
255 	InsertResult Move (SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther,
256 			Iterator a_oHere);
257 		// Remove an item from another skip list and insert it into
258 		// ourselves.
259 		// Just like an Erase() followed by an Insert(), except that
260 		// there's no possibility of the operation failing.
261 
262 	void Move (SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther,
263 			Iterator a_oFirst, Iterator a_oLast);
264 		// Remove a range of items from another skip-list and insert
265 		// them into ourselves.
266 		// Just like an Erase() followed by an Insert(), except that
267 		// there's no possibility of the operation failing.
268 
269 	void Move (SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther);
270 		// Move all items from the other skip-list to ourself.
271 		// The current skip-list must be empty.
272 
273 	bool CanMove (const SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther)
274 			const;
275 		// Returns true if the two skip lists can move items between
276 		// each other.
277 
278 	void Assign (Status_t &a_reStatus,
279 			const SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther);
280 		// Assign the contents of the other skip list to ourselves.
281 
282 	Iterator Find (const KEY &a_rKey);
283 		// Find the given item in the list.  Returns End() if not found.
284 
285 	ConstIterator Find (const KEY &a_rKey) const;
286 		// Find the given item in the list.  Returns End() if not found.
287 
288 	Iterator LowerBound (const KEY &a_rKey);
289 		// Return the position of the first item that's >= the key.
290 
291 	ConstIterator LowerBound (const KEY &a_rKey) const;
292 		// Return the position of the first item that's >= the key.
293 
294 	Iterator UpperBound (const KEY &a_rKey);
295 		// Return the position of the first item that's > the key.
296 
297 	ConstIterator UpperBound (const KEY &a_rKey) const;
298 		// Return the position of the first item that's > the key.
299 
300 	size_t GetSizeOfLargestNode (void) const;
301 		// Return the size of the largest possible skip-list node.
302 		//
303 		// (Not generally useful...needed by VariableSizeAllocator,
304 		// to make sure all free-space blocks can become part of an
305 		// in-place skip-list.)
306 
307 private:
308 
309 	Allocator_t &m_rNodeAllocator;
310 		// Where we get memory to allocate nodes.
311 
312 	bool m_bAllowDuplicates;
313 		// true if we allow duplicate elements.
314 
315 	int16_t m_nHeaderLevel;
316 		// How many valid pointers m_pHeader[] is holding.
317 
318 	Node *m_pHeader;
319 		// The beginning of the list.
320 
321 	Node *m_pSearchFinger, *m_pSearchFinger2;
322 		// Used to speed up searches, by caching the results of
323 		// previous searches.
324 
325 	uint32_t m_nItems;
326 		// The number of items in this list.
327 
328 	uint32_t m_nRandSeed;
329 		// The random-number seed.
330 
331 	bool m_bAllocateInternalNodesFromAllocator;
332 		// True if the skip list's internal nodes (i.e. the header
333 		// and search-fingers) should be allocated from the allocator.
334 		// False if they should be allocated from system memory.
335 		//
336 		// Since these nodes live for the lifetime of the skip-list,
337 		// allocating them from the allocator prevents the allocator
338 		// from being able to purge itself.
339 
340 	KEYFN m_oKeyFn;
341 		// How we extract a key from a value.
342 
343 	PRED m_oPred;
344 		// How we compare keys to each other.
345 
346 	void SearchLower (const KEY &a_rKey, Node *a_pTraverse) const;
347 		// Search for an item greater than or equal to a_rKey.
348 
349 	bool SearchExact (Node *a_pKey, Node *a_pTraverse) const;
350 		// Search for this exact item.  Returns true if it's found.
351 
352 	void SearchUpper (const KEY &a_rKey, Node *a_pTraverse) const;
353 		// Search for an item greater than a_rKey.
354 
355 	void SearchEnd (Node *a_pTraverse) const;
356 		// Point to the end of the list.
357 
358 	void InsertNode (Node *a_pNewNode, int16_t a_nNewLevel,
359 			Node *a_pTraverse);
360 		// Insert a new node into the skip list.  Assume a_pTraverse is
361 		// set up.
362 
363 	Node *RemoveNode (Node *a_pToRemove, Node *a_pTraverse,
364 			int16_t *a_pLevel = NULL);
365 		// Remove the given node from the skip list.  Assume a_pTraverse
366 		// is set up.
367 		// Returns the node that got removed, and optionally backpatches
368 		// its level.
369 
370 	Node *GetNewNode (int16_t a_nForwardPointers);
371 		// Allocate a new node with the given number of forward
372 		// pointers.  Returns NULL if something goes wrong.
373 
374 	Node *GetNewNodeOfRandomLevel (int16_t &a_rnLevel);
375 		// Allocate a new node with a random number of forward pointers.
376 		// Returns NULL if something goes wrong; otherwise, a_rnLevel
377 		// gets backpatched with the number of levels.
378 
379 	void DeleteNode (int16_t a_nForwardPointers, Node *a_pToDelete);
380 		// Delete a node.
381 
382 	void DeallocateNode (int16_t a_nForwardPointers, Node *a_pToDelete);
383 		// Deallocate a node's storage.
384 
385 	int16_t Rand (void);
386 		// Get another random number.
387 
388 	#ifdef DEBUG_SKIPLIST
389 	bool m_bDebug;
390 	#endif // DEBUG_SKIPLIST
391 		// true if the invariant should be checked.
392 };
393 
394 
395 
396 // The default node allocator.  Allocates 64K at a time.
397 template <class KEY, class VALUE, class KEYFN, class PRED,
398 	int HC, class ALLOC>
399 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Allocator_t
400 	SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::sm_oNodeAllocator (65536);
401 
402 
403 
404 // Default constructor.  Must be followed by Init().
405 template <class KEY, class VALUE, class KEYFN, class PRED,
406 	int HC, class ALLOC>
SkipList(const PRED & a_rPred,Allocator_t & a_rAlloc)407 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::SkipList (const PRED &a_rPred,
408 		Allocator_t &a_rAlloc)
409 	: m_rNodeAllocator (a_rAlloc), m_oPred (a_rPred)
410 {
411 	// Set up some defaults.
412 	m_bAllowDuplicates = false;
413 	m_nHeaderLevel = 0;
414 	m_pHeader = NULL;
415 	m_pSearchFinger = NULL;
416 	m_pSearchFinger2 = NULL;
417 	m_nItems = 0;
418 	m_nRandSeed = 0;
419 	m_bAllocateInternalNodesFromAllocator = false;
420 #ifdef DEBUG_SKIPLIST
421 	m_bDebug = false;
422 
423 	// Make sure we're intact.
424 	Invariant();
425 #endif // DEBUG_SKIPLIST
426 }
427 
428 
429 
430 // Constructor.  Specify whether or not duplicates are allowed, and
431 // provide a random number seed.
432 template <class KEY, class VALUE, class KEYFN, class PRED,
433 	int HC, class ALLOC>
SkipList(Status_t & a_reStatus,bool a_bAllowDuplicates,const InitParams & a_rInitParams,const PRED & a_rPred,Allocator_t & a_rAlloc)434 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::SkipList (Status_t &a_reStatus,
435 		bool a_bAllowDuplicates, const InitParams &a_rInitParams,
436 		const PRED &a_rPred, Allocator_t &a_rAlloc)
437 	: m_rNodeAllocator (a_rAlloc), m_oPred (a_rPred)
438 {
439 	// Make sure they didn't start us off with an error.
440 	assert (a_reStatus == g_kNoError);
441 
442 	// Set up some defaults.
443 	m_bAllowDuplicates = false;
444 	m_nHeaderLevel = 0;
445 	m_pHeader = NULL;
446 	m_pSearchFinger = NULL;
447 	m_pSearchFinger2 = NULL;
448 	m_nItems = 0;
449 	m_nRandSeed = 0;
450 	m_bAllocateInternalNodesFromAllocator = false;
451 	#ifdef DEBUG_SKIPLIST
452 	m_bDebug = false;
453 	#endif // DEBUG_SKIPLIST
454 
455 	// Init() does all the work.
456 	Init (a_reStatus, a_bAllowDuplicates, a_rInitParams);
457 }
458 
459 
460 
461 // Construction method.  Specify whether or not duplicates are allowed,
462 // and provide a random number seed.
463 template <class KEY, class VALUE, class KEYFN, class PRED,
464 	int HC, class ALLOC>
465 void
Init(Status_t & a_reStatus,bool a_bAllowDuplicates,const InitParams & a_rInitParams)466 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Init (Status_t &a_reStatus,
467 	bool a_bAllowDuplicates, const InitParams &a_rInitParams)
468 {
469 	// Make sure they didn't start us off with an error.
470 	assert (a_reStatus == g_kNoError);
471 
472 	// Make sure we haven't been initialized already.
473 	assert (m_pHeader == NULL);
474 
475 	// Fill in the blanks.
476 	m_bAllowDuplicates = a_bAllowDuplicates;
477 	m_nHeaderLevel = 0;
478 	m_nItems = 0;
479 	m_nRandSeed = a_rInitParams.m_nRandSeed;
480 	m_bAllocateInternalNodesFromAllocator
481 		= a_rInitParams.m_bAllocateInternalNodesFromAllocator;
482 
483 	// Allocate our necessary nodes.
484 	if (m_bAllocateInternalNodesFromAllocator)
485 	{
486 		m_pHeader = GetNewNode (HEADERCHUNK);
487 		m_pSearchFinger = GetNewNode (HEADERCHUNK);
488 		m_pSearchFinger2 = GetNewNode (HEADERCHUNK);
489 	}
490 	else
491 	{
492 		// Do this from system memory, instead of the supplied allocator.
493 		// Otherwise, these "permanent" allocations won't allow the
494 		// allocator to purge itself during the lifetime of this skip-list.
495 		size_t nHeaderBytes = (size_t)(&(((Node *)0x80000000)
496 			->m_apForward[HEADERCHUNK])) - 0x80000000;
497 		m_pHeader = (Node *) malloc (nHeaderBytes);
498 		m_pSearchFinger = (Node *) malloc (nHeaderBytes);
499 		m_pSearchFinger2 = (Node *) malloc (nHeaderBytes);
500 	}
501 	if (m_pHeader == NULL || m_pSearchFinger == NULL
502 		|| m_pSearchFinger2 == NULL)
503 	{
504 		if (m_bAllocateInternalNodesFromAllocator)
505 		{
506 			if (m_pSearchFinger2 != NULL)
507 				DeallocateNode (HEADERCHUNK, m_pSearchFinger2);
508 			if (m_pSearchFinger != NULL)
509 				DeallocateNode (HEADERCHUNK, m_pSearchFinger);
510 			if (m_pHeader != NULL)
511 				DeallocateNode (HEADERCHUNK, m_pHeader);
512 		}
513 		else
514 		{
515 			free (m_pSearchFinger2);
516 			free (m_pSearchFinger);
517 			free (m_pHeader);
518 		}
519 		m_pHeader = NULL;
520 		m_pSearchFinger = NULL;
521 		m_pSearchFinger2 = NULL;
522 		a_reStatus = g_kOutOfMemory;
523 		return;
524 	}
525 
526 	// Set up our nodes.
527 	//
528 	// The way we work, incrementing End() gets you Begin(), and
529 	// decrementing Begin() gets you End().  We implement that by using
530 	// our header node as a NULL-like sentinel node.
531 	#ifdef DEBUG_SKIPLIST
532 	m_pHeader->m_nLevel = HEADERCHUNK;
533 	m_pSearchFinger->m_nLevel = HEADERCHUNK;
534 	m_pSearchFinger2->m_nLevel = HEADERCHUNK;
535 	#endif // DEBUG_SKIPLIST
536 	new ((void *)(&(m_pHeader->m_oValue))) VALUE;
537 	new ((void *)(&(m_pSearchFinger->m_oValue))) VALUE;
538 	new ((void *)(&(m_pSearchFinger2->m_oValue))) VALUE;
539 	m_pHeader->m_pBackward = m_pHeader;
540 	m_pSearchFinger->m_pBackward = m_pHeader;
541 	m_pSearchFinger2->m_pBackward = m_pHeader;
542 	for (int16_t nI = 0; nI < HEADERCHUNK; nI++)
543 	{
544 		m_pHeader->m_apForward[nI] = m_pHeader;
545 		m_pSearchFinger->m_apForward[nI] = m_pHeader;
546 		m_pSearchFinger2->m_apForward[nI] = m_pHeader;
547 	}
548 
549 	// Make sure we're intact.
550 	#ifdef DEBUG_SKIPLIST
551 	Invariant();
552 	#endif // DEBUG_SKIPLIST
553 }
554 
555 
556 
557 // Destructor.
558 template <class KEY, class VALUE, class KEYFN, class PRED,
559 	int HC, class ALLOC>
~SkipList(void)560 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::~SkipList (void)
561 {
562 	// Make sure we're intact.
563 	#ifdef DEBUG_SKIPLIST
564 	Invariant();
565 	#endif // DEBUG_SKIPLIST
566 
567 	// If we have anything to delete, delete it.
568 	if (m_pHeader != NULL)
569 	{
570 		// Delete everything in the list.
571 		Erase (Begin(), End());
572 
573 		// Free up our extra nodes.
574 		m_pSearchFinger2->m_oValue.~VALUE();
575 		m_pSearchFinger->m_oValue.~VALUE();
576 		m_pHeader->m_oValue.~VALUE();
577 		if (m_bAllocateInternalNodesFromAllocator)
578 		{
579 			DeallocateNode (HEADERCHUNK, m_pSearchFinger2);
580 			DeallocateNode (HEADERCHUNK, m_pSearchFinger);
581 			DeallocateNode (HEADERCHUNK, m_pHeader);
582 		}
583 		else
584 		{
585 			free (m_pSearchFinger2);
586 			free (m_pSearchFinger);
587 			free (m_pHeader);
588 		}
589 	}
590 }
591 
592 
593 
594 #ifdef DEBUG_SKIPLIST
595 
596 // Set whether to run the skip-list invariant before and after methods.
597 template <class KEY, class VALUE, class KEYFN, class PRED,
598 	int HC, class ALLOC>
599 void
SetDebug(bool a_bDebug)600 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::SetDebug (bool a_bDebug)
601 {
602 	// Easy enough.
603 	m_bDebug = a_bDebug;
604 }
605 
606 #endif // DEBUG_SKIPLIST
607 
608 
609 
610 // Insert an item into the list.
611 template <class KEY, class VALUE, class KEYFN, class PRED,
612 	int HC, class ALLOC>
613 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::InsertResult
Insert(Status_t & a_reStatus,const VALUE & a_rValue)614 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Insert (Status_t &a_reStatus,
615 	const VALUE &a_rValue)
616 {
617 	Node *pNewNode;
618 		// The new node being inserted.
619 	int16_t nNewLevel;
620 		// The level of the new node.
621 	InsertResult oInsertResult;
622 		// The result of the insertion.
623 
624 	// Make sure we're intact.
625 	#ifdef DEBUG_SKIPLIST
626 	Invariant();
627 	#endif // DEBUG_SKIPLIST
628 
629 	// Make sure they didn't start us off with an error.
630 	assert (a_reStatus == g_kNoError);
631 
632 	// Make sure we have been initialized properly.
633 	assert (m_pHeader != NULL);
634 
635 	// Find where to put this key.  (Put equal keys at the upper bound.)
636 	SearchUpper (m_oKeyFn (a_rValue), m_pSearchFinger);
637 
638 	// Insert this node if there's no duplicate already in here.
639 	if (m_bAllowDuplicates
640 	|| (pNewNode = m_pSearchFinger->m_apForward[0],
641 		pNewNode == m_pHeader
642 		|| m_oPred (m_oKeyFn (pNewNode->m_oValue),
643 			m_oKeyFn (a_rValue))))
644 	{
645 		// Generate a node of random level.
646 		pNewNode = GetNewNodeOfRandomLevel (nNewLevel);
647 		if (pNewNode == NULL)
648 		{
649 			// We couldn't allocate space.
650 			a_reStatus = g_kOutOfMemory;
651 			oInsertResult.m_itPosition = End();
652 			oInsertResult.m_bInserted = false;
653 			return oInsertResult;
654 		}
655 
656 		// Install the value.
657 		new ((void *)(&(pNewNode->m_oValue))) VALUE (a_rValue);
658 
659 		// Put it into the skip list here.
660 		InsertNode (pNewNode, nNewLevel, m_pSearchFinger);
661 
662 		// Let them know where we put it, and that we did insert it.
663 		oInsertResult.m_itPosition = Iterator (pNewNode);
664 		oInsertResult.m_bInserted = true;
665 	}
666 	else
667 	{
668 		// We didn't insert it.  Show them the equal item.
669 		oInsertResult.m_itPosition = Iterator (pNewNode);
670 		oInsertResult.m_bInserted = false;
671 	}
672 
673 	// Make sure we're intact.
674 	#ifdef DEBUG_SKIPLIST
675 	Invariant();
676 	#endif // DEBUG_SKIPLIST
677 
678 	// Let them know what happened.
679 	return oInsertResult;
680 }
681 
682 
683 
684 // Insert an item into the list, at this exact location, if it's safe.
685 // Returns where it was really inserted.
686 template <class KEY, class VALUE, class KEYFN, class PRED,
687 	int HC, class ALLOC>
688 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Iterator
Insert(Status_t & a_reStatus,Iterator a_oPosition,const VALUE & a_rValue)689 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Insert (Status_t &a_reStatus,
690 	Iterator a_oPosition, const VALUE &a_rValue)
691 {
692 	const KEY &rKey = m_oKeyFn (a_rValue);
693 		// The key of what they're inserting.
694 	Node *pNewNode;
695 		// The node we're inserting.
696 	int16_t nNewLevel;
697 		// The level it's at.
698 	Iterator oHere;
699 		// Where it gets inserted.
700 
701 	// Make sure we're intact.
702 	#ifdef DEBUG_SKIPLIST
703 	Invariant();
704 	#endif // DEBUG_SKIPLIST
705 
706 	// Make sure they didn't start us off with an error.
707 	assert (a_reStatus == g_kNoError);
708 
709 	// Make sure we have been initialized properly.
710 	assert (m_pHeader != NULL);
711 
712 	// According to STL semantics, the insertion point must immediately
713 	// follow a_oPosition.  To fit more naturally with skip-list
714 	// semantics, the insertion point needs to precede a_oPosition.
715 	if (a_oPosition != End())
716 		++a_oPosition;
717 
718 	// The new item has to fit where this iterator points, and we must
719 	// be able to find this iterator's node in the list.
720 	Iterator oBefore = a_oPosition; --oBefore;
721 	if ((a_oPosition.m_pNode != m_pHeader
722 		&& m_oPred (m_oKeyFn (a_oPosition.m_pNode->m_oValue), rKey))
723 	|| (oBefore.m_pNode != m_pHeader
724 		&& m_oPred (rKey, m_oKeyFn (oBefore.m_pNode->m_oValue)))
725 	|| !SearchExact (a_oPosition.m_pNode, m_pSearchFinger))
726 	{
727 		// Don't use their iterator.
728 		oHere = Insert (a_reStatus, a_rValue).m_itPosition;
729 	}
730 
731 	// Insert this node if we always insert, or if there's no duplicate
732 	// already.
733 	else if (m_bAllowDuplicates
734 	|| (pNewNode = m_pSearchFinger->m_apForward[0]->m_apForward[0],
735 		pNewNode == m_pHeader
736 		|| m_oPred (rKey, m_oKeyFn (pNewNode->m_oValue))))
737 	{
738 		// Generate a node of random level.
739 		pNewNode = GetNewNodeOfRandomLevel (nNewLevel);
740 		if (pNewNode == NULL)
741 		{
742 			// We couldn't allocate space.
743 			a_reStatus = g_kOutOfMemory;
744 			oHere = End();
745 		}
746 		else
747 		{
748 			// Install the value.
749 			new ((void *)(&(pNewNode->m_oValue))) VALUE (a_rValue);
750 
751 			// Put it into the skip list here.
752 			InsertNode (pNewNode, nNewLevel, m_pSearchFinger);
753 
754 			// Let them know where we put it.
755 			oHere = Iterator (pNewNode);
756 		}
757 	}
758 
759 	// We didn't insert it.  Show them the equal item.
760 	else
761 		oHere = Iterator (pNewNode);
762 
763 	// Make sure we're intact.
764 	#ifdef DEBUG_SKIPLIST
765 	Invariant();
766 	#endif // DEBUG_SKIPLIST
767 
768 	// Let our caller know what happened.
769 	return oHere;
770 }
771 
772 
773 
774 // Insert a range of items from another skip-list.
775 template <class KEY, class VALUE, class KEYFN, class PRED,
776 	int HC, class ALLOC>
777 void
Insert(Status_t & a_reStatus,ConstIterator a_oFirst,ConstIterator a_oLast)778 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Insert (Status_t &a_reStatus,
779 	ConstIterator a_oFirst, ConstIterator a_oLast)
780 {
781 	ConstIterator oHere;
782 		// The next item to insert.
783 
784 	// Make sure they didn't start us off with an error.
785 	assert (a_reStatus == g_kNoError);
786 
787 	// Make sure we have been initialized properly.
788 	assert (m_pHeader != NULL);
789 
790 	// Try to insert every item they gave us.
791 	for (oHere = a_oFirst; oHere != a_oLast; oHere++)
792 	{
793 		Insert (a_reStatus, *oHere);
794 		if (a_reStatus != g_kNoError)
795 		{
796 			// BUG: this is messy.  If we can't insert the entire range,
797 			// we shouldn't insert any of it.  Fix this by preallocating
798 			// all necessary nodes.
799 			return;
800 		}
801 	}
802 }
803 
804 
805 
806 // Erase the item here.  Return the item following the one removed.
807 template <class KEY, class VALUE, class KEYFN, class PRED,
808 	int HC, class ALLOC>
809 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Iterator
Erase(Iterator a_oHere)810 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Erase (Iterator a_oHere)
811 {
812 	Node *pToRemove;
813 	int16_t nLevel;
814 		// The node being deleted, and its level.
815 
816 	// Make sure we have been initialized properly.
817 	assert (m_pHeader != NULL);
818 
819 	// Make sure we're intact.
820 	#ifdef DEBUG_SKIPLIST
821 	Invariant();
822 	#endif // DEBUG_SKIPLIST
823 
824 	// Don't let them erase End().
825 	if (a_oHere.m_pNode == m_pHeader)
826 		return Begin();
827 
828 	// If this iterator does not point to a current node, leave.
829 	// (This check also sets up the search finger for RemoveNode().)
830 	if (!SearchExact (a_oHere.m_pNode, m_pSearchFinger))
831 		return Begin();
832 
833 	// Erase it.
834 	pToRemove = RemoveNode (m_pSearchFinger->m_apForward[0]
835 		->m_apForward[0], m_pSearchFinger, &nLevel);
836 	DeleteNode (nLevel, pToRemove);
837 
838 	// Make sure we're intact.
839 	#ifdef DEBUG_SKIPLIST
840 	Invariant();
841 	#endif // DEBUG_SKIPLIST
842 
843 	// Return an iterator that points past the deleted node.
844 	return Iterator (m_pSearchFinger->m_apForward[0]->m_apForward[0]);
845 }
846 
847 
848 
849 // Erase a range of items in this list.  Return the item following the
850 // last one removed.
851 template <class KEY, class VALUE, class KEYFN, class PRED,
852 	int HC, class ALLOC>
853 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Iterator
Erase(Iterator a_oFirst,Iterator a_oLast)854 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Erase (Iterator a_oFirst,
855 	Iterator a_oLast)
856 {
857 	int16_t nI;
858 		// Used to loop through things.
859 	Node *pNode, *pToRemove;
860 		// Nodes we're examining and deleting.
861 	int16_t nLevel;
862 		// The level of each removed node.
863 
864 	// Make sure we're intact.
865 	#ifdef DEBUG_SKIPLIST
866 	Invariant();
867 	#endif // DEBUG_SKIPLIST
868 
869 	// Make sure we have been initialized properly.
870 	assert (m_pHeader != NULL);
871 
872 	// Make sure these iterators are in the right order.
873 	assert (a_oFirst == Begin()
874 		|| a_oLast == End()
875 		|| !m_oPred (m_oKeyFn (a_oLast.m_pNode->m_oValue),
876 			m_oKeyFn (a_oFirst.m_pNode->m_oValue)));
877 
878 	// If the first item to be removed is the end of the list, then
879 	// nothing needs to be done.
880 	if (a_oFirst == End())
881 		return End();
882 
883 	// A skip-list's range-delete doesn't involve a rebalancing for
884 	// every node deleted, like a tree structure's range-delete would.
885 	// Here, we just generate search fingers for each end of the
886 	// range, and fix the forward/backward pointers in one shot.
887 	// We still have to loop through the deleted range in order to
888 	// delete the nodes, but that's nowhere near the cost of a
889 	// rebalance per node.  Spiffy, huh?
890 
891 	// First, search for the beginning of the range to delete.
892 	// Abort if we can't find it.
893 	if (!SearchExact (a_oFirst.m_pNode, m_pSearchFinger))
894 		return End();
895 
896 	// Use that as a base for the second search.
897 	for (nI = 0; nI < m_nHeaderLevel; nI++)
898 		m_pSearchFinger2->m_apForward[nI]
899 			= m_pSearchFinger->m_apForward[nI];
900 
901 	// Now search for the end of the range to delete.
902 	// Abort if we can't find it.
903 	if (!SearchExact (a_oLast.m_pNode, m_pSearchFinger2))
904 		return End();
905 
906 	// Loop through the removed nodes, destroy the values inside,
907 	// and deallocate the nodes.
908 	pNode = a_oFirst.m_pNode;
909 	while (pNode != a_oLast.m_pNode)
910 	{
911 		// Get the node to destroy.
912 		pToRemove = pNode;
913 		pNode = pNode->m_apForward[0];
914 
915 		// Destroy it.
916 		pToRemove = RemoveNode (pToRemove, m_pSearchFinger, &nLevel);
917 		DeleteNode (nLevel, pToRemove);
918 	}
919 
920 	// Make sure we're intact.
921 	#ifdef DEBUG_SKIPLIST
922 	Invariant();
923 	#endif // DEBUG_SKIPLIST
924 
925 	// Return the end of the removed range.
926 	return a_oLast;
927 }
928 
929 
930 
931 // Empty the list.
932 template <class KEY, class VALUE, class KEYFN, class PRED,
933 	int HC, class ALLOC>
934 void
Clear(void)935 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Clear (void)
936 {
937 	// Make sure we have been initialized properly.
938 	assert (m_pHeader != NULL);
939 
940 	// Easy enough.
941 	Erase (Begin(), End());
942 
943 	// Since there are no nodes left, it's OK to "fix the dice" at
944 	// zero again.
945 	m_nHeaderLevel = 0;
946 }
947 
948 
949 
950 // Remove an item from another skip list and insert it into ourselves.
951 // Just like an Erase() followed by an Insert(), except that there's no
952 // possibility of the operation failing.
953 template <class KEY, class VALUE, class KEYFN, class PRED,
954 	int HC, class ALLOC>
955 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::InsertResult
Move(SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> & a_rOther,Iterator a_oHere)956 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Move
957 	(SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther, Iterator a_oHere)
958 {
959 	Node *pNode;
960 		// The node we're moving.
961 	int16_t nLevel;
962 		// The level of the node we're moving.
963 	InsertResult oInsertResult;
964 		// The result of the insertion.
965 
966 	// Make sure we're intact.
967 	#ifdef DEBUG_SKIPLIST
968 	Invariant();
969 	#endif // DEBUG_SKIPLIST
970 
971 	// Make sure we have been initialized properly.
972 	assert (m_pHeader != NULL);
973 
974 	// Make sure the skip-lists can move items between themselves.
975 	assert (CanMove (a_rOther));
976 
977 	// Don't let them move End().
978 	assert (a_oHere.m_pNode != a_rOther.m_pHeader);
979 
980 	// Get a reference to the key of the value being moved.
981 	const KEY &rKey = m_oKeyFn (a_oHere.m_pNode->m_oValue);
982 
983 	// Find where to put this key.  (Put equal keys at the upper bound.)
984 	SearchUpper (rKey, m_pSearchFinger);
985 
986 	// Move this node if there's no duplicate already in here.
987 	if (m_bAllowDuplicates
988 	|| (pNode = m_pSearchFinger->m_apForward[0],
989 		pNode == m_pHeader
990 			|| m_oPred (m_oKeyFn (pNode->m_oValue), rKey)))
991 	{
992 		bool bFound;
993 		// true if this node was found in the other skip list.
994 
995 		// Make sure the other list is intact.
996 		#ifdef DEBUG_SKIPLIST
997 		a_rOther.Invariant();
998 		#endif // DEBUG_SKIPLIST
999 
1000 		// Find this node in the other skip list.
1001 		bFound = a_rOther.SearchExact (a_oHere.m_pNode,
1002 			a_rOther.m_pSearchFinger);
1003 
1004 		// Make sure this iterator points to a current node.
1005 		assert (bFound);
1006 
1007 		// Remove it from that skip list.
1008 		pNode = a_rOther.RemoveNode (a_oHere.m_pNode,
1009 			a_rOther.m_pSearchFinger, &nLevel);
1010 
1011 		// If the node we're about to add is a higher level than any
1012 		// node we've seen so far, keep track of the new maximum.
1013 		if (m_nHeaderLevel < nLevel)
1014 			m_nHeaderLevel = nLevel;
1015 
1016 		// Put it into the skip list here.
1017 		InsertNode (pNode, nLevel, m_pSearchFinger);
1018 
1019 		// Let them know where we put it, and that we did insert it.
1020 		oInsertResult.m_itPosition = Iterator (pNode);
1021 		oInsertResult.m_bInserted = true;
1022 	}
1023 	else
1024 	{
1025 		// We didn't insert it.  Show them the equal item.
1026 		oInsertResult.m_itPosition = Iterator (pNode);
1027 		oInsertResult.m_bInserted = false;
1028 	}
1029 
1030 	// Make sure we're intact.
1031 	#ifdef DEBUG_SKIPLIST
1032 	Invariant();
1033 	#endif // DEBUG_SKIPLIST
1034 
1035 	// Let them know what happened.
1036 	return oInsertResult;
1037 }
1038 
1039 
1040 
1041 // Remove a range of items from another skip-list and insert them
1042 // into ourselves.
1043 // Just like an Erase() followed by an Insert(), except that there's no
1044 // possibility of the operation failing.
1045 template <class KEY, class VALUE, class KEYFN, class PRED,
1046 	int HC, class ALLOC>
1047 void
Move(SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> & a_rOther,Iterator a_oFirst,Iterator a_oLast)1048 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Move
1049 	(SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther, Iterator a_oFirst,
1050 	Iterator a_oLast)
1051 {
1052 	Iterator oHere, oNext;
1053 		// The item we're moving.
1054 
1055 	// Make sure we have been initialized properly.
1056 	assert (m_pHeader != NULL);
1057 
1058 	// Loop through all the items, move each one.
1059 	oHere = a_oFirst;
1060 	while (oHere != a_oLast)
1061 	{
1062 		// Keep track of the next item to move.
1063 		oNext = oHere;
1064 		oNext++;
1065 
1066 		// Move this item.
1067 		Move (a_rOther, oHere);
1068 
1069 		// Loop back and move the next one.
1070 		oHere = oNext;
1071 	}
1072 }
1073 
1074 
1075 
1076 // Move all items from the other skip-list to ourself.
1077 template <class KEY, class VALUE, class KEYFN, class PRED,
1078 	int HC, class ALLOC>
1079 void
Move(SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> & a_rOther)1080 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Move
1081 	(SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther)
1082 {
1083 	Node *p;
1084 		// Used to swap structures.
1085 
1086 	// Make sure we're all intact.
1087 	#ifdef DEBUG_SKIPLIST
1088 	Invariant();
1089 	a_rOther.Invariant();
1090 	#endif // DEBUG_SKIPLIST
1091 
1092 	// Make sure the skip-lists can move items between themselves.
1093 	assert (CanMove (a_rOther));
1094 
1095 	// Make sure we're empty.
1096 	assert (m_nItems == 0);
1097 
1098 	// Swap the header & search fingers.
1099 	p = m_pHeader;
1100 	m_pHeader = a_rOther.m_pHeader;
1101 	a_rOther.m_pHeader = p;
1102 	p = m_pSearchFinger;
1103 	m_pSearchFinger = a_rOther.m_pSearchFinger;
1104 	a_rOther.m_pSearchFinger = p;
1105 	p = m_pSearchFinger2;
1106 	m_pSearchFinger2 = a_rOther.m_pSearchFinger2;
1107 	a_rOther.m_pSearchFinger2 = p;
1108 
1109 	// Use their header level, if it's bigger than ours.
1110 	if (m_nHeaderLevel < a_rOther.m_nHeaderLevel)
1111 		m_nHeaderLevel = a_rOther.m_nHeaderLevel;
1112 	a_rOther.m_nHeaderLevel = 0;
1113 
1114 	// Now we have all their items.
1115 	m_nItems = a_rOther.m_nItems;
1116 	a_rOther.m_nItems = 0;
1117 
1118 	// Make sure we're all intact.
1119 	#ifdef DEBUG_SKIPLIST
1120 	Invariant();
1121 	a_rOther.Invariant();
1122 	#endif // DEBUG_SKIPLIST
1123 }
1124 
1125 
1126 
1127 // Returns true if the two skip lists can move items between
1128 // each other.
1129 template <class KEY, class VALUE, class KEYFN, class PRED,
1130 	int HC, class ALLOC>
1131 bool
CanMove(const SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> & a_rOther) const1132 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::CanMove
1133 	(const SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther) const
1134 {
1135 	// They can if they have the same allocator.
1136 	return (&m_rNodeAllocator == &a_rOther.m_rNodeAllocator);
1137 }
1138 
1139 
1140 
1141 // Assign the contents of the other skip list to ourselves.
1142 template <class KEY, class VALUE, class KEYFN, class PRED,
1143 	int HC, class ALLOC>
1144 void
Assign(Status_t & a_reStatus,const SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> & a_rOther)1145 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Assign (Status_t &a_reStatus,
1146 	const SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC> &a_rOther)
1147 {
1148 	Node *pBegin, *pEnd;
1149 		// Where we're looking in the other list.
1150 	Node *pHere;
1151 		// Where we're looking in our list.
1152 
1153 	// Make sure we're intact.
1154 	#ifdef DEBUG_SKIPLIST
1155 	Invariant();
1156 	#endif // DEBUG_SKIPLIST
1157 
1158 	// Make sure they didn't start us off with an error.
1159 	assert (a_reStatus == g_kNoError);
1160 
1161 	// Make sure we have been initialized properly.
1162 	assert (m_pHeader != NULL);
1163 
1164 	// Get the range of items from the other list.
1165 	pBegin = a_rOther.Begin().m_pNode;
1166 	pEnd = a_rOther.End().m_pNode;
1167 
1168 	// First, if we have more nodes than they do, erase enough of ours
1169 	// so that we have the same amount.
1170 	if (Size() > a_rOther.Size())
1171 	{
1172 		// Calculate the number of nodes to delete.
1173 		int32_t nToDelete = Size() - a_rOther.Size();
1174 
1175 		// Move forward that many items.
1176 		Iterator oToDelete = Begin();
1177 		while (--nToDelete >= 0)
1178 			oToDelete++;
1179 
1180 		// Delete those items.
1181 		Erase (Begin(), oToDelete);
1182 	}
1183 
1184 	// Start modifying our items here.
1185 	pHere = Begin().m_pNode;
1186 
1187 	// Next, insert as many items as we can, using the nodes already
1188 	// allocated in the list.
1189 	while (pHere != m_pHeader && pBegin != pEnd)
1190 	{
1191 		// Store the new item over the old one.
1192 		pHere->m_oValue = pBegin->m_oValue;
1193 
1194 		// Move forward.
1195 		pHere = pHere->m_apForward[0];
1196 		pBegin = pBegin->m_apForward[0];
1197 	}
1198 
1199 	// If we ran out of nodes, insert the rest in the normal way.
1200 	if (pBegin != pEnd)
1201 		Insert (a_reStatus, ConstIterator (pBegin),
1202 			ConstIterator (pEnd));
1203 
1204 	// Make sure we're intact.
1205 	#ifdef DEBUG_SKIPLIST
1206 	Invariant();
1207 	#endif // DEBUG_SKIPLIST
1208 }
1209 
1210 
1211 
1212 // Find the given item in the list.  Returns End() if not found.
1213 template <class KEY, class VALUE, class KEYFN, class PRED,
1214 	int HC, class ALLOC>
1215 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Iterator
Find(const KEY & a_rKey)1216 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Find (const KEY &a_rKey)
1217 {
1218 	Iterator oHere;
1219 		// What we found.
1220 
1221 	// Make sure we're intact.
1222 	#ifdef DEBUG_SKIPLIST
1223 	Invariant();
1224 	#endif // DEBUG_SKIPLIST
1225 
1226 	// Make sure we have been initialized properly.
1227 	assert (m_pHeader != NULL);
1228 
1229 	// Look for the item.
1230 	oHere = LowerBound (a_rKey);
1231 
1232 	// LowerBound() returns the first item >= the key.  So if this item
1233 	// is greater than what they were asking for, that means we didn't
1234 	// find it.
1235 	if (oHere == End()
1236 	|| m_oPred (a_rKey, m_oKeyFn (oHere.m_pNode->m_oValue)))
1237 		return End();
1238 	else
1239 		return oHere;
1240 }
1241 
1242 
1243 
1244 // Find the given item in the list.  Returns End() if not found.
1245 template <class KEY, class VALUE, class KEYFN, class PRED,
1246 	int HC, class ALLOC>
1247 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::ConstIterator
Find(const KEY & a_rKey) const1248 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Find (const KEY &a_rKey) const
1249 {
1250 	ConstIterator oHere;
1251 		// What we found.
1252 
1253 	// Make sure we're intact.
1254 	#ifdef DEBUG_SKIPLIST
1255 	Invariant();
1256 	#endif // DEBUG_SKIPLIST
1257 
1258 	// Make sure we have been initialized properly.
1259 	assert (m_pHeader != NULL);
1260 
1261 	// Look for the item.
1262 	oHere = LowerBound (a_rKey);
1263 
1264 	// LowerBound() returns the first item >= the key.  So if this item
1265 	// is greater than what they were asking for, that means we didn't
1266 	// find it.
1267 	if (oHere == End()
1268 	|| m_oPred (a_rKey, m_oKeyFn (oHere.m_pNode->m_oValue)))
1269 		return End();
1270 	else
1271 		return oHere;
1272 }
1273 
1274 
1275 
1276 // Return the position of the first item that's >= the key.
1277 template <class KEY, class VALUE, class KEYFN, class PRED,
1278 	int HC, class ALLOC>
1279 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Iterator
LowerBound(const KEY & a_rKey)1280 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::LowerBound (const KEY &a_rKey)
1281 {
1282 	// Make sure we have been initialized properly.
1283 	assert (m_pHeader != NULL);
1284 
1285 	// Search for the first item >= the key.
1286 	SearchLower (a_rKey, m_pSearchFinger);
1287 
1288 	// Return what we found.
1289 	return Iterator (m_pSearchFinger->m_apForward[0]->m_apForward[0]);
1290 }
1291 
1292 
1293 
1294 // Return the position of the first item that's >= the key.
1295 template <class KEY, class VALUE, class KEYFN, class PRED,
1296 	int HC, class ALLOC>
1297 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::ConstIterator
LowerBound(const KEY & a_rKey) const1298 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::LowerBound (const KEY &a_rKey)
1299 	const
1300 {
1301 	// Make sure we have been initialized properly.
1302 	assert (m_pHeader != NULL);
1303 
1304 	// Search for the first item >= the key.
1305 	SearchLower (a_rKey, m_pSearchFinger);
1306 
1307 	// Return what we found.
1308 	return ConstIterator (m_pSearchFinger->m_apForward[0]
1309 		->m_apForward[0]);
1310 }
1311 
1312 
1313 
1314 // Return the position of the first item that's > the key.
1315 template <class KEY, class VALUE, class KEYFN, class PRED,
1316 	int HC, class ALLOC>
1317 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Iterator
UpperBound(const KEY & a_rKey)1318 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::UpperBound (const KEY &a_rKey)
1319 {
1320 	// Make sure we have been initialized properly.
1321 	assert (m_pHeader != NULL);
1322 
1323 	// Search for the first item > the key.
1324 	SearchUpper (a_rKey, m_pSearchFinger);
1325 
1326 	// Return what we found.
1327 	return Iterator (m_pSearchFinger->m_apForward[0]->m_apForward[0]);
1328 }
1329 
1330 
1331 
1332 // Return the position of the first item that's > the key.
1333 template <class KEY, class VALUE, class KEYFN, class PRED,
1334 	int HC, class ALLOC>
1335 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::ConstIterator
UpperBound(const KEY & a_rKey) const1336 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::UpperBound (const KEY &a_rKey)
1337 	const
1338 {
1339 	// Make sure we have been initialized properly.
1340 	assert (m_pHeader != NULL);
1341 
1342 	// Search for the first item > the key.
1343 	SearchUpper (a_rKey, m_pSearchFinger);
1344 
1345 	// Return what we found.
1346 	return ConstIterator (m_pSearchFinger->m_apForward[0]
1347 		->m_apForward[0]);
1348 }
1349 
1350 
1351 
1352 // Return the size of the largest possible skip-list node.
1353 template <class KEY, class VALUE, class KEYFN, class PRED,
1354 	int HC, class ALLOC>
1355 size_t
GetSizeOfLargestNode(void) const1356 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::GetSizeOfLargestNode (void) const
1357 {
1358 	// Easy enough.
1359 	return (size_t)(&(((Node *)0x80000000)->m_apForward[HEADERCHUNK]))
1360 		- 0x80000000;
1361 }
1362 
1363 
1364 
1365 // Search for an item greater than or equal to a_rKey.
1366 template <class KEY, class VALUE, class KEYFN, class PRED,
1367 	int HC, class ALLOC>
1368 void
SearchLower(const KEY & a_rKey,Node * a_pTraverse) const1369 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::SearchLower (const KEY &a_rKey,
1370 	Node *a_pTraverse) const
1371 {
1372 	Node *pCurrentNode;
1373 		// Where we're searching.
1374 	int16_t nCurrentLevel;
1375 		// The level we've searched so far.
1376 	Node *pLastFinger;
1377 		// A node that we know is < the key.
1378 	Node *pAlreadyChecked;
1379 		// A node that we know is >= the key.
1380 
1381 	// Make sure we're intact.
1382 	#ifdef DEBUG_SKIPLIST
1383 	Invariant();
1384 	#endif // DEBUG_SKIPLIST
1385 
1386 	// Make sure we have been initialized properly.
1387 	assert (m_pHeader != NULL);
1388 
1389 	// See how much of the previous search we can reuse.
1390 	pCurrentNode = m_pHeader;
1391 	pLastFinger = m_pHeader;
1392 	pAlreadyChecked = m_pHeader;
1393 	nCurrentLevel = m_nHeaderLevel;
1394 	while (--nCurrentLevel >= 0)
1395 	{
1396 		Node *pCurrentFinger;
1397 			// What's at this level.
1398 
1399 		// See what's at this level.
1400 		pCurrentFinger = a_pTraverse->m_apForward[nCurrentLevel];
1401 
1402 		// If this is what we found before, OR if there's nothing here,
1403 		// OR we haven't gone past what we're trying to find, then
1404 		// there's a chance we can reuse the search at this level.
1405 		if (pCurrentFinger == pLastFinger
1406 		|| pCurrentFinger == m_pHeader
1407 		|| m_oPred (m_oKeyFn (pCurrentFinger->m_oValue), a_rKey))
1408 		{
1409 			// Look at the item past the current search finger.
1410 			Node *pNextFinger
1411 				= pCurrentFinger->m_apForward[nCurrentLevel];
1412 
1413 			// If there's nothing here, OR what's here is >= what we're
1414 			// looking for, then we can reuse all of this level's
1415 			// search.
1416 			if (pNextFinger == m_pHeader
1417 			|| pNextFinger == pAlreadyChecked
1418 			|| !m_oPred (m_oKeyFn (pNextFinger->m_oValue), a_rKey))
1419 			{
1420 				// We can reuse all of this level's search.
1421 				pCurrentNode = pCurrentFinger;
1422 				pLastFinger = pCurrentFinger;
1423 				pAlreadyChecked = pNextFinger;
1424 			}
1425 			else
1426 			{
1427 				// We can reuse this level's search, but we have to
1428 				// start looking here.
1429 				pCurrentNode = pCurrentFinger;
1430 				nCurrentLevel++;
1431 				break;
1432 			}
1433 		}
1434 		else
1435 		{
1436 			// We can't reuse this level.  Redo it.
1437 			nCurrentLevel++;
1438 			break;
1439 		}
1440 	}
1441 
1442 	// Now search for the item in the list.
1443 	while (--nCurrentLevel >= 0)
1444 	{
1445 		Node *pNextNode;
1446 		while (pNextNode = pCurrentNode->m_apForward[nCurrentLevel],
1447 			pNextNode != pAlreadyChecked && pNextNode != m_pHeader
1448 			&& m_oPred (m_oKeyFn (pNextNode->m_oValue), a_rKey))
1449 		{
1450 			pCurrentNode = pNextNode;
1451 		}
1452 		pAlreadyChecked = pCurrentNode->m_apForward[nCurrentLevel];
1453 		a_pTraverse->m_apForward[nCurrentLevel] = pCurrentNode;
1454 	}
1455 
1456 	// Make sure we're intact.
1457 	#ifdef DEBUG_SKIPLIST
1458 	Invariant();
1459 	#endif // DEBUG_SKIPLIST
1460 }
1461 
1462 
1463 
1464 // Search for this exact item.  Returns true if it's found.
1465 template <class KEY, class VALUE, class KEYFN, class PRED,
1466 	int HC, class ALLOC>
1467 bool
SearchExact(Node * a_pKey,Node * a_pTraverse) const1468 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::SearchExact (Node *a_pKey,
1469 	Node *a_pTraverse) const
1470 {
1471 	Node *pFound;
1472 		// What we found.
1473 	int16_t nI;
1474 		// Used to iterate through levels.
1475 
1476 	// Make sure we're intact.
1477 	#ifdef DEBUG_SKIPLIST
1478 	Invariant();
1479 	#endif // DEBUG_SKIPLIST
1480 
1481 	// Make sure we have been initialized properly.
1482 	assert (m_pHeader != NULL);
1483 
1484 	// If they passed us End(), just search to the end and succeed.
1485 	if (a_pKey == m_pHeader)
1486 	{
1487 		SearchEnd (a_pTraverse);
1488 		return true;
1489 	}
1490 
1491 	// Find the lower bound.
1492 	SearchLower (m_oKeyFn (a_pKey->m_oValue), a_pTraverse);
1493 
1494 	// Run through the equal range, look for this exact item.
1495 	for (pFound = a_pTraverse->m_apForward[0]->m_apForward[0];
1496 		 pFound != m_pHeader && pFound != a_pKey;
1497 		 pFound = pFound->m_apForward[0])
1498 	{
1499 		// Advance the search finger.
1500 		for (nI = 0;
1501 			 nI < m_nHeaderLevel
1502 			 	&& a_pTraverse->m_apForward[nI]->m_apForward[nI]
1503 					== pFound;
1504 			 nI++)
1505 		{
1506 			a_pTraverse->m_apForward[nI] = pFound;
1507 		}
1508 	}
1509 
1510 	// Make sure we're intact.
1511 	#ifdef DEBUG_SKIPLIST
1512 	Invariant();
1513 	#endif // DEBUG_SKIPLIST
1514 
1515 	// Let them know if we succeeded.
1516 	return (pFound == a_pKey);
1517 }
1518 
1519 
1520 
1521 // Search for an item greater than a_rKey.
1522 template <class KEY, class VALUE, class KEYFN, class PRED,
1523 	int HC, class ALLOC>
1524 void
SearchUpper(const KEY & a_rKey,Node * a_pTraverse) const1525 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::SearchUpper (const KEY &a_rKey,
1526 	Node *a_pTraverse) const
1527 {
1528 	Node *pCurrentNode;
1529 		// Where we're searching.
1530 	int16_t nCurrentLevel;
1531 		// The level we've searched so far.
1532 	Node *pLastFinger;
1533 		// A node that we know is <= the key.
1534 	Node *pAlreadyChecked;
1535 		// A node that we know is > the key.
1536 
1537 	// Make sure we're intact.
1538 	#ifdef DEBUG_SKIPLIST
1539 	Invariant();
1540 	#endif // DEBUG_SKIPLIST
1541 
1542 	// Make sure we have been initialized properly.
1543 	assert (m_pHeader != NULL);
1544 
1545 	// See how much of the previous search we can reuse.
1546 	pCurrentNode = m_pHeader;
1547 	pLastFinger = m_pHeader;
1548 	pAlreadyChecked = m_pHeader;
1549 	nCurrentLevel = m_nHeaderLevel;
1550 	while (--nCurrentLevel >= 0)
1551 	{
1552 		Node *pCurrentFinger;
1553 			// What's at this level.
1554 
1555 		// See what's at this level.
1556 		pCurrentFinger = a_pTraverse->m_apForward[nCurrentLevel];
1557 
1558 		// If this is what we found before, OR if there's nothing here,
1559 		// OR we haven't gone past what we're trying to find, then
1560 		// there's a chance we can reuse the search at this level.
1561 		if (pCurrentFinger == pLastFinger
1562 		|| pCurrentFinger == m_pHeader
1563 		|| !m_oPred (a_rKey, m_oKeyFn (pCurrentFinger->m_oValue)))
1564 		{
1565 			// Look at the item past the current search finger.
1566 			Node *pNextFinger
1567 				= pCurrentFinger->m_apForward[nCurrentLevel];
1568 
1569 			// If there's nothing here, OR what's here is > what we're
1570 			// looking for, then we can reuse all of this level's
1571 			// search.
1572 			if (pNextFinger == m_pHeader
1573 			|| pNextFinger == pAlreadyChecked
1574 			|| m_oPred (a_rKey, m_oKeyFn (pNextFinger->m_oValue)))
1575 			{
1576 				// We can reuse all of this level's search.
1577 				pCurrentNode = pCurrentFinger;
1578 				pLastFinger = pCurrentFinger;
1579 				pAlreadyChecked = pNextFinger;
1580 			}
1581 			else
1582 			{
1583 				// We can reuse this level's search, but we have to
1584 				// start looking here.
1585 				pCurrentNode = pCurrentFinger;
1586 				nCurrentLevel++;
1587 				break;
1588 			}
1589 		}
1590 		else
1591 		{
1592 			// We can't reuse this level.  Redo it.
1593 			nCurrentLevel++;
1594 			break;
1595 		}
1596 	}
1597 
1598 	// Now search for the item in the list.
1599 	while (--nCurrentLevel >= 0)
1600 	{
1601 		Node *pNextNode;
1602 		while (pNextNode = pCurrentNode->m_apForward[nCurrentLevel],
1603 			pNextNode != pAlreadyChecked && pNextNode != m_pHeader
1604 			&& !m_oPred (a_rKey, m_oKeyFn (pNextNode->m_oValue)))
1605 		{
1606 			pCurrentNode = pNextNode;
1607 		}
1608 		pAlreadyChecked = pCurrentNode->m_apForward[nCurrentLevel];
1609 		a_pTraverse->m_apForward[nCurrentLevel] = pCurrentNode;
1610 	}
1611 
1612 	// Make sure we're intact.
1613 	#ifdef DEBUG_SKIPLIST
1614 	Invariant();
1615 	#endif // DEBUG_SKIPLIST
1616 }
1617 
1618 
1619 
1620 // Point to the end of the list.
1621 template <class KEY, class VALUE, class KEYFN, class PRED,
1622 	int HC, class ALLOC>
1623 void
SearchEnd(Node * a_pTraverse) const1624 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::SearchEnd (Node *a_pTraverse)
1625 	const
1626 {
1627 	// Make sure we have been initialized properly.
1628 	assert (m_pHeader != NULL);
1629 
1630 	// Make sure we're intact.
1631 	#ifdef DEBUG_SKIPLIST
1632 	Invariant();
1633 	#endif // DEBUG_SKIPLIST
1634 
1635 	// Point every level of the traverse array to the last node before
1636 	// the end.
1637 	Node *pLastNode = a_pTraverse->m_apForward[m_nHeaderLevel - 1];
1638 	int16_t nCurrentLevel = m_nHeaderLevel;
1639 	while (--nCurrentLevel >= 0)
1640 	{
1641 		Node *pNextNode;
1642 		while (pNextNode = pLastNode->m_apForward[nCurrentLevel],
1643 				pNextNode != m_pHeader)
1644 		{
1645 			pLastNode = pNextNode;
1646 		}
1647 		a_pTraverse->m_apForward[nCurrentLevel] = pLastNode;
1648 	}
1649 
1650 	// Make sure we're intact.
1651 	#ifdef DEBUG_SKIPLIST
1652 	Invariant();
1653 	#endif // DEBUG_SKIPLIST
1654 }
1655 
1656 
1657 
1658 // Insert a new node into the skip list.  Assume a_pTraverse is
1659 // set up.
1660 template <class KEY, class VALUE, class KEYFN, class PRED,
1661 	int HC, class ALLOC>
1662 void
InsertNode(Node * a_pNewNode,int16_t a_nNewLevel,Node * a_pTraverse)1663 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::InsertNode (Node *a_pNewNode,
1664 	int16_t a_nNewLevel, Node *a_pTraverse)
1665 {
1666 	// Make sure we're intact.
1667 	#ifdef DEBUG_SKIPLIST
1668 	Invariant();
1669 	#endif // DEBUG_SKIPLIST
1670 
1671 	// Set up the backward link of the new node.
1672 	a_pNewNode->m_pBackward = a_pTraverse->m_apForward[0];
1673 
1674 	// Modify all levels of pointers.
1675 	while (--a_nNewLevel >= 0)
1676 	{
1677 		// Insert ourselves where the traverse array points.
1678 		a_pNewNode->m_apForward[a_nNewLevel]
1679 			= a_pTraverse->m_apForward[a_nNewLevel]
1680 				->m_apForward[a_nNewLevel];
1681 		a_pTraverse->m_apForward[a_nNewLevel]->m_apForward[a_nNewLevel]
1682 			= a_pNewNode;
1683 
1684 		// Point the traverse array at the new node.
1685 		a_pTraverse->m_apForward[a_nNewLevel] = a_pNewNode;
1686 	}
1687 
1688 	// Set up the backward link of the node after the new one.
1689 	a_pNewNode->m_apForward[0]->m_pBackward = a_pNewNode;
1690 
1691 	// That's one more node in the list.
1692 	m_nItems++;
1693 
1694 	// Make sure we're intact.
1695 	#ifdef DEBUG_SKIPLIST
1696 	Invariant();
1697 	#endif // DEBUG_SKIPLIST
1698 }
1699 
1700 
1701 
1702 // Remove the given node from the skip list.  Assume a_pTraverse is
1703 // set up.
1704 // Returns the node that got removed, and optionally backpatches its
1705 // level.
1706 template <class KEY, class VALUE, class KEYFN, class PRED,
1707 	int HC, class ALLOC>
1708 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Node *
RemoveNode(Node * a_pToRemove,Node * a_pTraverse,int16_t * a_pLevel)1709 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::RemoveNode (Node *a_pToRemove,
1710 	Node *a_pTraverse, int16_t *a_pLevel)
1711 {
1712 	int16_t nI;
1713 		// Used to loop through skip-list levels.
1714 	Node *pCurrentNode;
1715 		// A node that's pointing to the node we're removing.
1716 
1717 	// Make sure we're intact.
1718 	#ifdef DEBUG_SKIPLIST
1719 	Invariant();
1720 	#endif // DEBUG_SKIPLIST
1721 
1722 	// Make sure this traversal array is set up to remove this node.
1723 	assert (a_pTraverse->m_apForward[0]->m_apForward[0] == a_pToRemove);
1724 
1725 	// Remove this node from all levels where it appears.
1726 	for (nI = 0;
1727 		 nI < m_nHeaderLevel
1728 		 && (pCurrentNode = a_pTraverse->m_apForward[nI],
1729 			pCurrentNode->m_apForward[nI] == a_pToRemove);
1730 		 nI++)
1731 	{
1732 		pCurrentNode->m_apForward[nI] = a_pToRemove->m_apForward[nI];
1733 	}
1734 
1735 	// Make sure the node had as many levels as we expected.
1736 	#ifdef DEBUG_SKIPLIST
1737 	assert (nI == a_pToRemove->m_nLevel);
1738 	#endif // DEBUG_SKIPLIST
1739 
1740 	// Remove this node from the back-links.
1741 	a_pTraverse->m_apForward[0]->m_apForward[0]->m_pBackward
1742 		= a_pTraverse->m_apForward[0];
1743 
1744 	// That's one less item in the list.
1745 	m_nItems--;
1746 
1747 	// Give them the level of this node, if they asked for it.
1748 	if (a_pLevel != NULL)
1749 		*a_pLevel = nI;
1750 
1751 	// Make sure we're intact.
1752 	#ifdef DEBUG_SKIPLIST
1753 	Invariant();
1754 	#endif // DEBUG_SKIPLIST
1755 
1756 	// Return the node we removed.
1757 	return a_pToRemove;
1758 }
1759 
1760 
1761 
1762 // Allocate a new node with the given number of forward pointers.
1763 // Returns NULL if something goes wrong.
1764 template <class KEY, class VALUE, class KEYFN, class PRED,
1765 	int HC, class ALLOC>
1766 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Node *
GetNewNode(int16_t a_nForwardPointers)1767 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::GetNewNode
1768 	(int16_t a_nForwardPointers)
1769 {
1770 	size_t nBytes;
1771 		// The number of bytes this node needs.
1772 	Node *pNode;
1773 		// The node we allocate.
1774 
1775 	// Calculate the number of bytes it takes to represent a node with
1776 	// this many forward pointers.
1777 	nBytes = (size_t)(&(((Node *)0x80000000)
1778 		->m_apForward[a_nForwardPointers])) - 0x80000000;
1779 
1780 	// Allocate space.
1781 	pNode = (Node *) m_rNodeAllocator.Allocate (a_nForwardPointers - 1,
1782 		nBytes);
1783 	if (pNode == NULL)
1784 		return NULL;
1785 
1786 	// Set the number of forward pointers.
1787 	#ifdef DEBUG_SKIPLIST
1788 	pNode->m_nLevel = a_nForwardPointers;
1789 	#endif // DEBUG_SKIPLIST
1790 
1791 	// Return what we allocated.
1792 	return pNode;
1793 }
1794 
1795 
1796 
1797 // Allocate a new node with a random number of forward pointers.
1798 // Returns NULL if something goes wrong; otherwise, a_rnLevel gets
1799 // backpatched with the number of levels.
1800 template <class KEY, class VALUE, class KEYFN, class PRED,
1801 	int HC, class ALLOC>
1802 typename SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Node *
GetNewNodeOfRandomLevel(int16_t & a_rnLevel)1803 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::GetNewNodeOfRandomLevel
1804 	(int16_t &a_rnLevel)
1805 {
1806 	// Fix the dice (as described in the skip-list paper).
1807 	int16_t nHighestLevel = (m_nHeaderLevel == HEADERCHUNK)
1808 		? HEADERCHUNK : (m_nHeaderLevel + 1);
1809 
1810 	// Now generate a random level for the node.  (12055 / 32768 equals
1811 	// our skip list's p, which is 1/e.)
1812 	int16_t nNewLevel = 1;
1813 	while (nNewLevel < nHighestLevel && Rand() < 12055)
1814 		nNewLevel++;
1815 
1816 	// Keep track of the new maximum.
1817 	if (nNewLevel == nHighestLevel)
1818 		m_nHeaderLevel = nHighestLevel;
1819 
1820 	// Allocate a node of this size.
1821 	a_rnLevel = nNewLevel;
1822 	return GetNewNode (nNewLevel);
1823 }
1824 
1825 
1826 
1827 // Delete a node.
1828 template <class KEY, class VALUE, class KEYFN, class PRED,
1829 	int HC, class ALLOC>
1830 void
DeleteNode(int16_t a_nForwardPointers,Node * a_pToDelete)1831 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::DeleteNode
1832 	(int16_t a_nForwardPointers, Node *a_pToDelete)
1833 {
1834 	// Make sure they gave us a node to delete.
1835 	assert (a_pToDelete != NULL);
1836 
1837 	// Delete the value we contain.
1838 	a_pToDelete->m_oValue.~VALUE();
1839 
1840 	// Deallocate the node's storage.
1841 	DeallocateNode (a_nForwardPointers, a_pToDelete);
1842 }
1843 
1844 
1845 
1846 // Deallocate a node's storage.
1847 template <class KEY, class VALUE, class KEYFN, class PRED,
1848 	int HC, class ALLOC>
1849 void
DeallocateNode(int16_t a_nForwardPointers,Node * a_pToDelete)1850 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::DeallocateNode
1851 	(int16_t a_nForwardPointers, Node *a_pToDelete)
1852 {
1853 	// Make sure they gave us a node to deallocate.
1854 	assert (a_pToDelete != NULL);
1855 
1856 	// Calculate the number of bytes it takes to represent a node with
1857 	// this many forward pointers.
1858 	size_t nBytes = (size_t)(&(((Node *)0x80000000)
1859 		->m_apForward[a_nForwardPointers])) - 0x80000000;
1860 
1861 	// Return the memory to our node allocator.
1862 	m_rNodeAllocator.Deallocate (a_nForwardPointers - 1,
1863 		nBytes, (void *)a_pToDelete);
1864 }
1865 
1866 
1867 
1868 // Get another random number.
1869 template <class KEY, class VALUE, class KEYFN, class PRED,
1870 	int HC, class ALLOC>
1871 int16_t
Rand(void)1872 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Rand (void)
1873 {
1874 	// I'd use the normal rand() but it's WAAAY too slow.
1875 	// Feel free to adjust this routine all you want.
1876 	m_nRandSeed = m_nRandSeed * 42989 + 17891;
1877 	return int16_t (m_nRandSeed & 32767);
1878 }
1879 
1880 
1881 
1882 #ifdef DEBUG_SKIPLIST
1883 
1884 template <class KEY, class VALUE, class KEYFN, class PRED,
1885 	int HC, class ALLOC>
1886 void
Invariant(void) const1887 SkipList<KEY,VALUE,KEYFN,PRED,HC,ALLOC>::Invariant (void) const
1888 {
1889 	int32_t nI;
1890 		// Used to loop through things.
1891 	Node *pSearchFinger;
1892 		// Used to verify the integrity of the forward pointers.
1893 	Node *pCurrentNode;
1894 		// The node whose integrity we are presently verifying.
1895 	Node *pPreviousNode;
1896 		// The node before the current one.
1897 	uint32_t nItems;
1898 		// The number of items we found.
1899 
1900 	// Only check the invariant if they requested we do.
1901 	if (!m_bDebug)
1902 		return;
1903 
1904 	// If the skip list is not fully initialized, we have less to check.
1905 	if (m_pHeader == NULL)
1906 	{
1907 		assert (m_nHeaderLevel == 0);
1908 		assert (m_pSearchFinger == NULL);
1909 		assert (m_pSearchFinger2 == NULL);
1910 		assert (m_nItems == 0);
1911 		return;
1912 	}
1913 
1914 	// Make sure the skip list level isn't bigger than the compiled-in
1915 	// maximum.
1916 	assert (m_nHeaderLevel <= HEADERCHUNK);
1917 
1918 	// Calculate the number of bytes it takes to represent a node with
1919 	// this many forward pointers.
1920 	size_t nBytes = (size_t)(&(((Node *)0x80000000)
1921 		->m_apForward[HEADERCHUNK])) - 0x80000000;
1922 
1923 	// We're going to run through the skip list and make sure all the
1924 	// forward pointers are correct.  For that, we need a temporary
1925 	// search finger to keep track of the traversal.
1926 	pSearchFinger = (Node *) alloca (nBytes);
1927 	pSearchFinger->m_nLevel = 0;
1928 	pSearchFinger->m_pBackward = NULL;
1929 	for (nI = 0; nI < HEADERCHUNK; nI++)
1930 		pSearchFinger->m_apForward[nI] = m_pHeader;
1931 
1932 	// The backward link for the header node points to the last item in
1933 	// the list.  So find the last item in the list.
1934 	pPreviousNode = m_pHeader;
1935 	while (pPreviousNode->m_apForward[0] != m_pHeader)
1936 		pPreviousNode = pPreviousNode->m_apForward[0];
1937 
1938 	// Run through the skip list, make sure the forward pointers and
1939 	// backward pointers are intact.
1940 	pCurrentNode = m_pHeader;
1941 	nItems = 0;
1942 	for (;;)
1943 	{
1944 		int32_t nLevel;
1945 			// The level of the current node.
1946 
1947 		// At least one forward pointer of the temporary search finger
1948 		// points to the current node.  The number of forward pointers
1949 		// that point to the current node, must be equal to its assigned
1950 		// level.  So start by calculating what level this node must be.
1951 		nLevel = 0;
1952 		while (nLevel < HEADERCHUNK
1953 				&& pSearchFinger->m_apForward[nLevel] == pCurrentNode)
1954 			nLevel++;
1955 
1956 		// Make sure the node has that many forward pointers.
1957 		assert (pCurrentNode->m_nLevel == nLevel);
1958 
1959 		// Make sure the backward pointer is intact.
1960 		assert (pCurrentNode->m_pBackward == pPreviousNode);
1961 
1962 		// Make sure that the nodes are in proper sorted order.
1963 		if (pPreviousNode != m_pHeader && pCurrentNode != m_pHeader)
1964 		{
1965 			if (m_bAllowDuplicates)
1966 			{
1967 				// The current item has to be >= the previous item.
1968 				assert (!m_oPred (m_oKeyFn (pCurrentNode->m_oValue),
1969 					m_oKeyFn (pPreviousNode->m_oValue)));
1970 			}
1971 			else
1972 			{
1973 				// The current item has to be > the previous item.
1974 				assert (m_oPred (m_oKeyFn (pPreviousNode->m_oValue),
1975 					m_oKeyFn (pCurrentNode->m_oValue)));
1976 			}
1977 		}
1978 
1979 		// If we're at the end of the list, stop.
1980 		if (pCurrentNode->m_apForward[0] == m_pHeader)
1981 			break;
1982 
1983 		// That's one more item we found.  (We put this here in order to
1984 		// avoid counting the header node as an item.)
1985 		nItems++;
1986 
1987 		// Move forward.
1988 		pPreviousNode = pCurrentNode;
1989 		pCurrentNode = pCurrentNode->m_apForward[0];
1990 		for (nI = 0; nI < nLevel; nI++)
1991 			pSearchFinger->m_apForward[nI]
1992 				= pSearchFinger->m_apForward[nI]->m_apForward[nI];
1993 	}
1994 
1995 	// Make sure the list has the expected number of items.
1996 	assert (m_nItems == nItems);
1997 }
1998 
1999 #endif // DEBUG_SKIPLIST
2000 
2001 
2002 
2003 #endif // __SKIPLIST_H__
2004