8#ifndef INCLUDED_BDLCC_SKIPLIST
9#define INCLUDED_BDLCC_SKIPLIST
424#include <bdlscm_version.h>
453#include <bsl_algorithm.h>
454#include <bsl_functional.h>
455#include <bsl_ostream.h>
456#include <bsl_vector.h>
458#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
467template <
class KEY,
class DATA>
476template<
class KEY,
class DATA>
553class SkipList_PoolManager;
598template<
class KEY,
class DATA>
602 typedef SkipList_PoolManager PoolManager;
609 PoolManager *d_poolManager_p;
641 void construct(
const KEY& key,
const DATA& data);
656template <
class KEY,
class DATA>
679 const KEY&
key()
const;
692template <
class KEY,
class DATA>
765 const KEY&
key()
const;
782template<
class KEY,
class DATA>
793#ifndef BDE_OMIT_INTERNAL_DEPRECATED
811 typedef SkipList_PoolManager PoolManager;
823 template <
class VECTOR,
class VALUE_TYPE>
830 k_MAX_NUM_LEVELS = 32,
847 PoolManager *d_poolManager_p;
854 template <
class KEY2,
class DATA2>
857 template <
class KEY2,
class DATA2>
865 static DATA& data(
const Pair *reference);
869 static const KEY& key(
const Pair *reference);
878 static Node *pairToNode(
Pair *reference);
881 static Node *pairToNode(
const Pair *reference);
889 void addNode(
bool *newFrontFlag,
Node *newNode);
897 void addNodeImpR(
bool *newFrontFlag,
Node *newNode,
bool lock);
911 void addNodeR(
bool *newFrontFlag,
Node *newNode);
919 int addNodeUnique(
bool *newFrontFlag,
Node *newNode);
929 int addNodeUniqueR(
bool *newFrontFlag,
Node *newNode);
938 Node *allocateNode(
int level,
const KEY& key,
const DATA& data);
950 void insertImp(
bool *newFrontFlag,
Node *location[],
Node *node);
962 void moveImp(
bool *newFrontFlag,
Node *location[],
Node *node);
972 void releaseNode(
Node *node);
981 template <
class VECTOR>
982 int removeAllMaybeUnlock(VECTOR *removed,
bool unlock);
991 template <
class VECTOR>
992 int removeAllImp(VECTOR *removed);
997 int removeNode(
Node *node);
1010 int updateNode(
bool *newFrontFlag,
1013 bool allowDuplicates);
1027 int updateNodeR(
bool *newFrontFlag,
1030 bool allowDuplicates);
1036 Node *backNode()
const;
1041 void checkInvariants()
const;
1045 Node *findNode(
const KEY& key)
const;
1049 Node *findNodeR(
const KEY& key)
const;
1055 Node *findNodeLowerBound(
const KEY& key)
const;
1061 Node *findNodeLowerBoundR(
const KEY& key)
const;
1067 Node *findNodeUpperBound(
const KEY& key)
const;
1073 Node *findNodeUpperBoundR(
const KEY& key)
const;
1077 Node *frontNode()
const;
1085 void lookupImpLowerBound(
Node *location[],
const KEY& key)
const;
1093 void lookupImpLowerBoundR(
Node *location[],
const KEY& key)
const;
1101 void lookupImpUpperBound(
Node *location[],
const KEY& key)
const;
1109 void lookupImpUpperBoundR(
Node *location[],
const KEY& key)
const;
1124 int skipBackward(
Node **node)
const;
1131 int skipForward(
Node **node)
const;
1184 void add(
const KEY& key,
const DATA& data,
bool *newFrontFlag = 0);
1193 bool *newFrontFlag = 0);
1208 bool *newFrontFlag = 0);
1225 bool *newFrontFlag = 0);
1236 bool *newFrontFlag = 0);
1243 int addUnique(
const KEY& key,
const DATA& data,
bool *newFrontFlag = 0);
1254 bool *newFrontFlag = 0);
1267 bool *newFrontFlag = 0);
1286 bool *newFrontFlag = 0);
1304 bool *newFrontFlag = 0);
1311 void addR(
const KEY& key,
const DATA& data,
bool *newFrontFlag = 0);
1322 bool *newFrontFlag = 0);
1334 bool *newFrontFlag = 0);
1343 int addUniqueR(
const KEY& key,
const DATA& data,
bool *newFrontFlag = 0);
1356 bool *newFrontFlag = 0);
1370 bool *newFrontFlag = 0);
1400#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
1401 int removeAll(std::pmr::vector<PairHandle> *removed);
1412#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
1428 bool *newFrontFlag = 0,
1429 bool allowDuplicates =
true);
1442 bool *newFrontFlag = 0,
1443 bool allowDuplicates =
true);
1496 bsl::ostream&
print(bsl::ostream& stream,
1498 int spacesPerLevel = 4)
const;
1684template <
class KEY,
class DATA>
1694template <
class KEY,
class DATA>
1700template<
class KEY,
class DATA>
1710template <
class KEY,
class DATA>
1711template <
class VECTOR,
class VALUE_TYPE>
1712class SkipList<KEY, DATA>::IsVector {
1716 static const bool value =
1718#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
1728template <
class KEY,
class DATA>
1746template <
class KEY,
class DATA>
1775: d_firstGuard(
bsl::min(lock1, lock2,
bsl::less<
bslmt::Mutex *>()))
1776, d_lastGuard(
bsl::max(lock1, lock2,
bsl::less<
bslmt::Mutex *>()))
1784template <
class KEY,
class DATA>
1791template <
class KEY,
class DATA>
1803template <
class KEY,
class DATA>
1811template <
class KEY,
class DATA>
1817, d_node_p(reference)
1821template <
class KEY,
class DATA>
1825: d_list_p(original.d_list_p)
1826, d_node_p(original.d_node_p
1827 ? d_list_p->addPairReferenceRaw(original.d_node_p)
1832template <
class KEY,
class DATA>
1840template <
class KEY,
class DATA>
1845 reset(rhs.d_list_p, 0);
1846 d_node_p = rhs.d_node_p ? d_list_p->addPairReferenceRaw(rhs.d_node_p) : 0;
1850template <
class KEY,
class DATA>
1857 d_list_p->releaseReferenceRaw(d_node_p);
1862template <
class KEY,
class DATA>
1872 *reference = d_node_p;
1876template <
class KEY,
class DATA>
1883 d_node_p = reference;
1887template <
class KEY,
class DATA>
1896template <
class KEY,
class DATA>
1900 return d_node_p != 0 && d_list_p != 0;
1903template <
class KEY,
class DATA>
1917template <
class KEY,
class DATA>
1931template<
class KEY,
class DATA>
1934 PoolManager *poolManager,
1938, d_poolManager_p(poolManager)
1940, d_allocator_p(
bslma::Default::allocator(basicAllocator))
1944template<
class KEY,
class DATA>
1950 d_node_p->d_key.~KEY();
1952 PoolUtil::deallocate(d_poolManager_p, d_node_p);
1956template<
class KEY,
class DATA>
1982template<
class KEY,
class DATA>
1988template<
class KEY,
class DATA>
1993 return reinterpret_cast<Pair *
>(node);
2001template<
class KEY,
class DATA>
2008template<
class KEY,
class DATA>
2021template<
class KEY,
class DATA>
2027 Node *node =
static_cast<Node *
>(
static_cast<void *
>(
2028 const_cast<Pair *
>(reference)));
2032template<
class KEY,
class DATA>
2038 const Node *node =
static_cast<const Node *
>(
2039 static_cast<const void *
>(reference));
2044template<
class KEY,
class DATA>
2056 return reinterpret_cast<IntPtr
>(&
reinterpret_cast<Node*
>(0)->d_ptrs);
2059template<
class KEY,
class DATA>
2061typename SkipList<KEY, DATA>::Node
2062 *SkipList<KEY, DATA>::pairToNode(
Pair *reference)
2064 return static_cast<Node *
>(
static_cast<void *
>(reference));
2067template<
class KEY,
class DATA>
2069typename SkipList<KEY, DATA>::Node
2070 *SkipList<KEY, DATA>::pairToNode(
const Pair *reference)
2072 return static_cast<Node *
>(
static_cast<void *
>(
2073 const_cast<Pair *
>(reference)));
2078template<
class KEY,
class DATA>
2079void SkipList<KEY, DATA>::addNode(
bool *newFrontFlag, Node *newNode)
2081 LockGuard guard(&d_lock);
2086 Node *location[k_MAX_NUM_LEVELS];
2087 lookupImpLowerBound(location, newNode->d_key);
2089 insertImp(newFrontFlag, location, newNode);
2092template<
class KEY,
class DATA>
2093void SkipList<KEY, DATA>::addNodeImpR(
bool *newFrontFlag,
2097 LockGuard lockGuard(&d_lock, !lock);
2099 lockGuard.release();
2105 Node *location[k_MAX_NUM_LEVELS];
2106 lookupImpUpperBoundR(location, newNode->d_key);
2108 insertImp(newFrontFlag, location, newNode);
2111template<
class KEY,
class DATA>
2113void SkipList<KEY, DATA>::addNodeR(
bool *newFrontFlag, Node *newNode)
2115 addNodeImpR(newFrontFlag, newNode,
true);
2118template<
class KEY,
class DATA>
2119int SkipList<KEY, DATA>::addNodeUnique(
bool *newFrontFlag, Node *newNode)
2121 LockGuard guard(&d_lock);
2126 Node *location[k_MAX_NUM_LEVELS];
2127 lookupImpLowerBound(location, newNode->d_key);
2129 Node *q = location[0];
2130 if (q != d_tail_p && q->d_key == newNode->d_key) {
2134 insertImp(newFrontFlag, location, newNode);
2139template<
class KEY,
class DATA>
2140int SkipList<KEY, DATA>::addNodeUniqueR(
bool *newFrontFlag, Node *newNode)
2142 LockGuard guard(&d_lock);
2147 Node *location[k_MAX_NUM_LEVELS];
2148 lookupImpLowerBoundR(location, newNode->d_key);
2150 Node *q = location[0];
2151 if (q != d_tail_p && q->d_key == newNode->d_key) {
2155 insertImp(newFrontFlag, location, newNode);
2160template<
class KEY,
class DATA>
2161SkipList_Node<KEY, DATA> *
2162SkipList<KEY, DATA>::allocateNode(
int level,
const KEY& key,
const DATA& data)
2164 int listLevel = d_listLevel;
2165 if (
level > listLevel) {
2166 level = listLevel + 1;
2172 NodeGuard nodeGuard(d_poolManager_p, node, d_allocator_p);
2174 nodeGuard.construct(key, data);
2177 node->d_ptrs[0].d_next_p = 0;
2182template<
class KEY,
class DATA>
2183void SkipList<KEY, DATA>::initialize()
2193 int nodeSizes[k_MAX_NUM_LEVELS];
2195 const IntPtr offset = offsetOfPtrs();
2196 for (
int i = 0; i < k_MAX_NUM_LEVELS; ++i) {
2197 IntPtr nodeSize = offset + (i + 1) *
sizeof(
typename Node::Ptrs);
2198 nodeSize = (nodeSize + alignMask) & ~alignMask;
2199 nodeSizes[i] =
static_cast<int>(nodeSize);
2211 for (
int i = 0; i < k_MAX_NUM_LEVELS; ++i) {
2220template<
class KEY,
class DATA>
2221void SkipList<KEY, DATA>::insertImp(
bool *newFrontFlag,
2228 int level = node->d_level;
2229 if (
level > d_listLevel) {
2232 d_listLevel =
level;
2234 node->d_ptrs[
level].d_prev_p = d_head_p;
2243 for (
int k =
level; k >= 0; --k) {
2244 Node *p = location[k]->d_ptrs[k].d_prev_p;
2245 Node *q = location[k];
2247 node->d_ptrs[k].d_prev_p = p;
2248 node->d_ptrs[k].d_next_p = q;
2250 p->d_ptrs[k].d_next_p = node;
2251 q->d_ptrs[k].d_prev_p = node;
2255 *newFrontFlag = (node->d_ptrs[0].d_prev_p == d_head_p);
2261template<
class KEY,
class DATA>
2262void SkipList<KEY, DATA>::moveImp(
bool *newFrontFlag,
2269 int level = node->d_level;
2272 for (
int k = 0; k <=
level; ++k) {
2273 Node *newP = location[k]->d_ptrs[k].d_prev_p;
2274 Node *newQ = location[k];
2276 if (newP == node || newQ == node) {
2283 Node *oldP = node->d_ptrs[k].d_prev_p;
2284 Node *oldQ = node->d_ptrs[k].d_next_p;
2286 oldQ->d_ptrs[k].d_prev_p = oldP;
2287 oldP->d_ptrs[k].d_next_p = oldQ;
2289 node->d_ptrs[k].d_prev_p = newP;
2290 node->d_ptrs[k].d_next_p = newQ;
2292 newP->d_ptrs[k].d_next_p = node;
2293 newQ->d_ptrs[k].d_prev_p = node;
2297 *newFrontFlag = (node->d_ptrs[0].d_prev_p == d_head_p);
2301template<
class KEY,
class DATA>
2302SkipList_Node<KEY, DATA> *SkipList<KEY, DATA>::popFrontImp()
2304 LockGuard guard(&d_lock);
2307 if (node == d_tail_p) {
2313 for (
int k =
level; k >= 0; --k) {
2314 Node *q = node->d_ptrs[k].d_next_p;
2315 q->d_ptrs[k].d_prev_p = d_head_p;
2325template<
class KEY,
class DATA>
2327void SkipList<KEY, DATA>::releaseNode(Node *node)
2331 const int refCnt = --node->d_refCount;
2334 node->d_data.~DATA();
2345template<
class KEY,
class DATA>
2346template<
class VECTOR>
2347int SkipList<KEY, DATA>::removeAllMaybeUnlock(VECTOR *removed,
bool unlock)
2349 typedef typename VECTOR::value_type ValueType;
2358 PairHandleFactory>::type FactoryType;
2362 Node *
const begin = d_head_p;
2364 int numRemoved = d_length;
2366 for (
int ii = 0; ii <= d_listLevel; ++ii) {
2372 for (Node *q = end;
begin != q; q = q->d_ptrs[0].d_prev_p) {
2373 q->d_ptrs[0].d_next_p = 0;
2382 const FactoryType factory(
this);
2388 removed->resize(oldSize + numRemoved);
2389 typename VECTOR::reverse_iterator removedIt = removed->rbegin();
2390 for (Node *q = end;
begin != q; q = q->d_ptrs[0].d_prev_p) {
2391 *removedIt++ = factory(q);
2393 BSLS_ASSERT(oldSize == removed->rend() - removedIt);
2396 for (Node *q = end;
begin != q; ) {
2397 Node *condemned = q;
2398 q = q->d_ptrs[0].d_prev_p;
2400 releaseNode(condemned);
2407template<
class KEY,
class DATA>
2408template<
class VECTOR>
2409int SkipList<KEY, DATA>::removeAllImp(VECTOR *removed)
2412 return removeAllMaybeUnlock(removed,
true);
2415template<
class KEY,
class DATA>
2416int SkipList<KEY, DATA>::removeNode(Node *node)
2420 LockGuard guard(&d_lock);
2422 if (0 == node->d_ptrs[0].d_next_p) {
2426 int level = node->d_level;
2428 for (
int k =
level; k >= 0; --k) {
2429 Node *p = node->d_ptrs[k].d_prev_p;
2430 Node *q = node->d_ptrs[k].d_next_p;
2432 q->d_ptrs[k].d_prev_p = p;
2433 p->d_ptrs[k].d_next_p = q;
2436 node->d_ptrs[0].d_next_p = 0;
2441template<
class KEY,
class DATA>
2442int SkipList<KEY, DATA>::updateNode(
bool *newFrontFlag,
2445 bool allowDuplicates)
2449 LockGuard guard(&d_lock);
2451 if (0 == node->d_ptrs[0].d_next_p) {
2455 Node *location[k_MAX_NUM_LEVELS];
2456 lookupImpLowerBound(location, newKey);
2458 if (!allowDuplicates) {
2459 Node *q = location[0];
2460 if (q != d_tail_p && q != node && q->d_key == newKey) {
2465 node->d_key = newKey;
2469 moveImp(newFrontFlag, location, node);
2474template<
class KEY,
class DATA>
2475int SkipList<KEY, DATA>::updateNodeR(
bool *newFrontFlag,
2478 bool allowDuplicates)
2482 LockGuard guard(&d_lock);
2484 if (0 == node->d_ptrs[0].d_next_p) {
2488 Node *location[k_MAX_NUM_LEVELS];
2490 if (!allowDuplicates) {
2491 lookupImpLowerBoundR(location, newKey);
2492 Node *p = location[0];
2493 if (p != d_tail_p && p != node && p->d_key == newKey) {
2498 lookupImpUpperBoundR(location, newKey);
2501 node->d_key = newKey;
2505 moveImp(newFrontFlag, location, node);
2511template<
class KEY,
class DATA>
2512SkipList_Node<KEY, DATA> *
2513SkipList<KEY, DATA>::backNode()
const
2515 LockGuard guard(&d_lock);
2518 if (node == d_head_p) {
2526template<
class KEY,
class DATA>
2527void SkipList<KEY, DATA>::checkInvariants()
const
2529 for (
int ii = 0; ii <= d_listLevel; ++ii) {
2531 Node *prev = d_head_p;
2542 for (
int jj = ii - 1; 0 <= jj; --jj) {
2548 BSLS_ASSERT(numNodes <= d_length); (void)numNodes;
2556template<
class KEY,
class DATA>
2557SkipList_Node<KEY, DATA> *SkipList<KEY, DATA>::findNode(
const KEY& key)
const
2559 Node *locator[k_MAX_NUM_LEVELS];
2561 LockGuard guard(&d_lock);
2562 lookupImpLowerBound(locator, key);
2564 Node *q = locator[0];
2565 if (q != d_tail_p && q->d_key == key) {
2573template<
class KEY,
class DATA>
2574SkipList_Node<KEY, DATA> *SkipList<KEY, DATA>::findNodeR(
const KEY& key)
const
2576 Node *locator[k_MAX_NUM_LEVELS];
2578 LockGuard guard(&d_lock);
2579 lookupImpUpperBoundR(locator, key);
2581 Node *p = locator[0];
2582 if (d_head_p != p) {
2583 p = p->d_ptrs[0].d_prev_p;
2584 if (d_head_p != p && key == p->d_key) {
2593template<
class KEY,
class DATA>
2594SkipList_Node<KEY, DATA> *SkipList<KEY, DATA>::findNodeLowerBound(
2595 const KEY& key)
const
2597 Node *locator[k_MAX_NUM_LEVELS];
2599 LockGuard guard(&d_lock);
2600 lookupImpLowerBound(locator, key);
2602 Node *q = locator[0];
2603 if (q != d_tail_p) {
2611template<
class KEY,
class DATA>
2612SkipList_Node<KEY, DATA> *SkipList<KEY, DATA>::findNodeUpperBound(
2613 const KEY& key)
const
2615 Node *locator[k_MAX_NUM_LEVELS];
2617 LockGuard guard(&d_lock);
2618 lookupImpUpperBound(locator, key);
2620 Node *q = locator[0];
2621 if (q != d_tail_p) {
2629template<
class KEY,
class DATA>
2630SkipList_Node<KEY, DATA> *SkipList<KEY, DATA>::findNodeLowerBoundR(
2631 const KEY& key)
const
2633 Node *locator[k_MAX_NUM_LEVELS];
2635 LockGuard guard(&d_lock);
2636 lookupImpLowerBoundR(locator, key);
2638 Node *q = locator[0];
2639 if (q != d_tail_p) {
2647template<
class KEY,
class DATA>
2648SkipList_Node<KEY, DATA> *SkipList<KEY, DATA>::findNodeUpperBoundR(
2649 const KEY& key)
const
2651 Node *locator[k_MAX_NUM_LEVELS];
2653 LockGuard guard(&d_lock);
2654 lookupImpUpperBoundR(locator, key);
2656 Node *q = locator[0];
2657 if (q != d_tail_p) {
2665template<
class KEY,
class DATA>
2666SkipList_Node<KEY, DATA> *SkipList<KEY, DATA>::frontNode()
const
2668 LockGuard guard(&d_lock);
2671 if (node == d_tail_p) {
2679template<
class KEY,
class DATA>
2680void SkipList<KEY, DATA>::lookupImpLowerBound(Node *location[],
2681 const KEY& key)
const
2684 for (
int k = d_listLevel; k >= 0; --k) {
2685 Node *q = p->d_ptrs[k].d_next_p;
2686 while (q != d_tail_p && q->d_key < key) {
2688 q = p->d_ptrs[k].d_next_p;
2696template<
class KEY,
class DATA>
2697void SkipList<KEY, DATA>::lookupImpLowerBoundR(Node *location[],
2698 const KEY& key)
const
2701 for (
int k = d_listLevel; k >= 0; --k) {
2702 Node *p = q->d_ptrs[k].d_prev_p;
2703 while (p != d_head_p && !(p->d_key < key)) {
2705 p = p->d_ptrs[k].d_prev_p;
2713template<
class KEY,
class DATA>
2714void SkipList<KEY, DATA>::lookupImpUpperBound(Node *location[],
2715 const KEY& key)
const
2718 for (
int k = d_listLevel; k >= 0; --k) {
2719 Node *q = p->d_ptrs[k].d_next_p;
2720 while (q != d_tail_p && !(key < q->d_key)) {
2722 q = p->d_ptrs[k].d_next_p;
2731template<
class KEY,
class DATA>
2732void SkipList<KEY, DATA>::lookupImpUpperBoundR(Node *location[],
2733 const KEY& key)
const
2736 for (
int k = d_listLevel; k >= 0; --k) {
2737 Node *p = q->d_ptrs[k].d_prev_p;
2738 while (p != d_head_p && key < p->d_key) {
2740 p = q->d_ptrs[k].d_prev_p;
2748template<
class KEY,
class DATA>
2749SkipList_Node<KEY, DATA> *
2750SkipList<KEY, DATA>::nextNode(Node *node)
const
2755 LockGuard guard(&d_lock);
2757 Node *
next = node->d_ptrs[0].d_next_p;
2758 if (0 == next || d_tail_p == next) {
2766template<
class KEY,
class DATA>
2767SkipList_Node<KEY, DATA> *
2768SkipList<KEY, DATA>::prevNode(Node *node)
const
2773 LockGuard guard(&d_lock);
2774 if (0 == node->d_ptrs[0].d_next_p) {
2778 Node *prev = node->d_ptrs[0].d_prev_p;
2779 if (d_head_p == prev) {
2787template<
class KEY,
class DATA>
2788int SkipList<KEY, DATA>::skipBackward(Node **node)
const
2792 Node *current = *node;
2797 LockGuard guard(&d_lock);
2799 if (0 == current->d_ptrs[0].d_next_p) {
2805 const int count = --current->d_refCount;
2809 Node *prev = current->d_ptrs[0].d_prev_p;
2810 if (d_head_p == prev) {
2820template<
class KEY,
class DATA>
2821int SkipList<KEY, DATA>::skipForward(Node **node)
const
2825 Node *current = *node;
2830 LockGuard guard(&d_lock);
2832 if (0 == current->d_ptrs[0].d_next_p) {
2838 const int count = --current->d_refCount;
2842 Node *next = current->d_ptrs[0].d_next_p;
2843 if (d_tail_p == next) {
2854template<
class KEY,
class DATA>
2860 Node *node = pairToNode(reference);
2865template<
class KEY,
class DATA>
2875template<
class KEY,
class DATA>
2881, d_allocator_p(
bslma::Default::allocator(basicAllocator))
2888template<
class KEY,
class DATA>
2891#if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
2898 Node *condemned = p;
2902 releaseNode(condemned);
2905 PoolUtil::deallocate(d_poolManager_p, d_head_p);
2906 PoolUtil::deallocate(d_poolManager_p, d_tail_p);
2908 PoolUtil::deletePoolManager(d_allocator_p, d_poolManager_p);
2912template<
class KEY,
class DATA>
2931 rhsElements.
reserve(rhs.d_length);
2933 node && node != rhs.d_tail_p;
2940 reinterpret_cast<Pair *
>(node));
2947 it != rhsElements.
end(); ++it) {
2948 Node *node = allocateNode(d_rand.randomLevel(),
2949 it->key(), it->data());
2950 addNodeImpR(0, node,
false);
2956template<
class KEY,
class DATA>
2960 Node *node = pairToNode(reference);
2966template<
class KEY,
class DATA>
2974 addRaw(&handle, key, data, newFrontFlag);
2975 result->reset(
this, handle);
2978template<
class KEY,
class DATA>
2984 Pair **zeroPair = 0;
2985 addRaw(zeroPair, key, data, newFrontFlag);
2988template<
class KEY,
class DATA>
2996 Node *node = allocateNode(level, key, data);
2999 *result =
reinterpret_cast<Pair *
>(node);
3002 addNode(newFrontFlag, node);
3005template<
class KEY,
class DATA>
3012 Node *node = allocateNode(level, key, data);
3015 *result =
reinterpret_cast<Pair *
>(node);
3018 int ret = addNodeUnique(newFrontFlag, node);
3031template<
class KEY,
class DATA>
3038 addAtLevelRaw(result, d_rand.randomLevel(), key, data, newFrontFlag);
3041template<
class KEY,
class DATA>
3049 int rc = addUniqueRaw(&handle, key, data, newFrontFlag);
3053 result->reset(
this, handle);
3057template<
class KEY,
class DATA>
3064 Pair **zeroPair = 0;
3065 return addUniqueRaw(zeroPair, key, data, newFrontFlag);
3068template<
class KEY,
class DATA>
3075 return addAtLevelUniqueRaw(result, d_rand.randomLevel(), key, data,
3081template<
class KEY,
class DATA>
3089 Node *node = allocateNode(level, key, data);
3092 *result =
reinterpret_cast<Pair *
>(node);
3095 addNodeR(newFrontFlag, node);
3098template<
class KEY,
class DATA>
3105 Node *node = allocateNode(level, key, data);
3108 *result =
reinterpret_cast<Pair *
>(node);
3111 int ret = addNodeUniqueR(newFrontFlag, node);
3124template<
class KEY,
class DATA>
3132 addRawR(&handle, key, data, newFrontFlag);
3133 result->reset(
this, handle);
3136template<
class KEY,
class DATA>
3142 Pair **zeroPair = 0;
3143 addRawR(zeroPair, key, data, newFrontFlag);
3146template<
class KEY,
class DATA>
3153 addAtLevelRawR(result, d_rand.randomLevel(), key, data, newFrontFlag);
3156template<
class KEY,
class DATA>
3163 int rc = addUniqueRawR(&handle, key, data, newFrontFlag);
3167 result->reset(
this, handle);
3172template<
class KEY,
class DATA>
3178 Pair **zeroPair = 0;
3179 return addUniqueRawR(zeroPair, key, data, newFrontFlag);
3182template<
class KEY,
class DATA>
3189 return addAtLevelUniqueRawR(result, d_rand.randomLevel(), key, data,
3195template<
class KEY,
class DATA>
3199 Node *node = popFrontImp();
3205 item->reset(
this,
reinterpret_cast<Pair *
>(node));
3214template<
class KEY,
class DATA>
3218 Node *node = popFrontImp();
3224 *item =
reinterpret_cast<Pair *
>(node);
3233template<
class KEY,
class DATA>
3237 if (0 == reference) {
3241 Node *node = pairToNode(reference);
3243 int ret = removeNode(node);
3252template<
class KEY,
class DATA>
3259template<
class KEY,
class DATA>
3263 return removeAllImp(removed);
3266template<
class KEY,
class DATA>
3270 return removeAllImp(removed);
3273#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
3274template<
class KEY,
class DATA>
3278 return removeAllImp(removed);
3282template<
class KEY,
class DATA>
3286 return removeAllImp(removed);
3289template<
class KEY,
class DATA>
3293 return removeAllImp(removed);
3296#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR
3297template<
class KEY,
class DATA>
3301 return removeAllImp(removed);
3307template<
class KEY,
class DATA>
3312 bool allowDuplicates)
3314 if (0 == reference) {
3318 Node *node = pairToNode(reference);
3319 return updateNode(newFrontFlag, node, newKey, allowDuplicates);
3322template<
class KEY,
class DATA>
3327 bool allowDuplicates)
3329 if (0 == reference) {
3333 Node *node = pairToNode(reference);
3334 return updateNodeR(newFrontFlag, node, newKey, allowDuplicates);
3338template<
class KEY,
class DATA>
3343 Node *node = pairToNode(reference);
3345 return const_cast<Pair *
>(reference);
3348template<
class KEY,
class DATA>
3352 Pair *backPtr =
reinterpret_cast<Pair *
>(backNode());
3354 back->reset(
this, backPtr);
3360template<
class KEY,
class DATA>
3364 *back =
reinterpret_cast<Pair *
>(backNode());
3365 return *back ? 0 : -1;
3368template<
class KEY,
class DATA>
3371 Node *locator[k_MAX_NUM_LEVELS];
3374 lookupImpLowerBound(locator, key);
3376 Node *q = locator[0];
3377 if (q != d_tail_p && q->
d_key == key) {
3384template<
class KEY,
class DATA>
3390 Pair *frontPtr =
reinterpret_cast<Pair *
>(frontNode());
3392 front->reset(
this, frontPtr);
3398template<
class KEY,
class DATA>
3404 *front =
reinterpret_cast<Pair *
>(frontNode());
3405 return *front ? 0 : -1;
3408template<
class KEY,
class DATA>
3414 return d_tail_p == d_head_p->d_ptrs[0].d_next_p;
3417template<
class KEY,
class DATA>
3426template<
class KEY,
class DATA>
3430 int spacesPerLevel)
const
3442 if (0 <= spacesPerLevel) {
3451 const int levelPlus1 = level + 1;
3454 node && node != d_tail_p;
3455 node = node->d_ptrs[0].d_next_p) {
3459 const int levelPlus2 = level + 2;
3461 stream <<
"level = " << node->d_level <<
"\n";
3489 node && node != d_tail_p;
3490 node = node->d_ptrs[0].d_next_p) {
3491 stream <<
"[ (level = " << node->d_level <<
") ";
3504 return stream << bsl::flush;
3509template<
class KEY,
class DATA>
3515 Pair *itemPtr =
reinterpret_cast<Pair *
>(findNode(key));
3517 item->reset(
this, itemPtr);
3523template<
class KEY,
class DATA>
3529 *item =
reinterpret_cast<Pair *
>(findNode(key));
3530 return *item ? 0 : -1;
3535template<
class KEY,
class DATA>
3541 Pair *itemPtr =
reinterpret_cast<Pair *
>(findNodeR(key));
3543 item->reset(
this, itemPtr);
3549template<
class KEY,
class DATA>
3555 *item =
reinterpret_cast<Pair *
>(findNodeR(key));
3556 return *item ? 0 : -1;
3561template<
class KEY,
class DATA>
3567 Pair *itemPtr =
reinterpret_cast<Pair *
>(findNodeLowerBound(key));
3569 item->reset(
this, itemPtr);
3575template<
class KEY,
class DATA>
3581 *item =
reinterpret_cast<Pair *
>(findNodeLowerBound(key));
3582 return *item ? 0 : -1;
3587template<
class KEY,
class DATA>
3590 const KEY& key)
const
3594 Pair *itemPtr =
reinterpret_cast<Pair *
>(findNodeLowerBoundR(key));
3596 item->reset(
this, itemPtr);
3602template<
class KEY,
class DATA>
3608 *item =
reinterpret_cast<Pair *
>(findNodeLowerBoundR(key));
3609 return *item ? 0 : -1;
3614template<
class KEY,
class DATA>
3617 const KEY& key)
const
3621 Pair *itemPtr =
reinterpret_cast<Pair *
>(findNodeUpperBound(key));
3623 item->reset(
this, itemPtr);
3629template<
class KEY,
class DATA>
3635 *item =
reinterpret_cast<Pair *
>(findNodeUpperBound(key));
3636 return *item ? 0 : -1;
3641template<
class KEY,
class DATA>
3644 const KEY& key)
const
3648 Pair *itemPtr =
reinterpret_cast<Pair *
>(findNodeUpperBoundR(key));
3650 item->reset(
this, itemPtr);
3656template<
class KEY,
class DATA>
3662 *item =
reinterpret_cast<Pair *
>(findNodeUpperBoundR(key));
3663 return *item ? 0 : -1;
3667template<
class KEY,
class DATA>
3671 if (0 == reference) {
3675 Node *node = pairToNode(reference);
3676 Node *nNode = nextNode(node);
3678 next->reset(
this,
reinterpret_cast<Pair *
>(nNode));
3684template<
class KEY,
class DATA>
3691 Node *node = pairToNode(reference);
3692 *next =
reinterpret_cast<Pair *
>(nextNode(node));
3694 return *next ? 0 : -1;
3697template<
class KEY,
class DATA>
3700 const Pair *reference)
const
3702 if (0 == reference) {
3706 Node *node = pairToNode(reference);
3707 Node *pNode = prevNode(node);
3709 prevPair->reset(
this,
reinterpret_cast<Pair *
>(pNode));
3715template<
class KEY,
class DATA>
3723 Node *node = pairToNode(reference);
3724 *prevPair =
reinterpret_cast<Pair *
>(prevNode(node));
3725 return *prevPair ? 0 : -1;
3728template<
class KEY,
class DATA>
3734 Node **node_p =
reinterpret_cast<Node **
>(&item->d_node_p);
3735 return skipBackward(node_p);
3738template<
class KEY,
class DATA>
3744 Node **node_p =
reinterpret_cast<Node **
>(item);
3745 return skipBackward(node_p);
3748template<
class KEY,
class DATA>
3754 Node **node_p =
reinterpret_cast<Node **
>(&item->d_node_p);
3755 return skipForward(node_p);
3758template<
class KEY,
class DATA>
3764 Node **node_p =
reinterpret_cast<Node **
>(item);
3765 return skipForward(node_p);
3770template<
class KEY,
class DATA>
3774 return d_allocator_p;
3780template<
class KEY,
class DATA>
3782 const SkipList<KEY, DATA>& rhs)
3794 for (SkipList_Node<KEY, DATA>
3795 *lhsNode = lhs.d_head_p->d_ptrs[0].d_next_p,
3796 *rhsNode = rhs.d_head_p->d_ptrs[0].d_next_p;
3798 lhsNode = lhsNode->d_ptrs[0].d_next_p,
3799 rhsNode = rhsNode->d_ptrs[0].d_next_p)
3801 if ((!lhsNode && !rhsNode)
3802 || (lhsNode == lhs.d_tail_p && rhsNode == rhs.d_tail_p)) {
3807 if (!lhsNode || !rhsNode
3808 || lhsNode == lhs.d_tail_p || rhsNode == rhs.d_tail_p) {
3814 if (!(lhsNode->d_key == rhsNode->d_key
3815 && lhsNode->d_data == rhsNode->d_data)) {
3825template<
class KEY,
class DATA>
3827 const SkipList<KEY, DATA>& rhs)
3839 for (SkipList_Node<KEY, DATA>
3840 *lhsNode = lhs.d_head_p->d_ptrs[0].d_next_p,
3841 *rhsNode = rhs.d_head_p->d_ptrs[0].d_next_p;
3843 lhsNode = lhsNode->d_ptrs[0].d_next_p,
3844 rhsNode = rhsNode->d_ptrs[0].d_next_p)
3846 if ((!lhsNode && !rhsNode)
3847 || (lhsNode == lhs.d_tail_p && rhsNode == rhs.d_tail_p)) {
3852 if (!lhsNode || !rhsNode
3853 || lhsNode == lhs.d_tail_p || rhsNode == rhs.d_tail_p) {
3859 if (!(lhsNode->d_key == rhsNode->d_key)
3860 || !(lhsNode->d_data == rhsNode->d_data)) {
3870template<
class KEY,
class DATA>
3873 const SkipList<KEY, DATA>& list)
3875 return list.print(stream, 0, -1);
#define BSLMF_NESTED_TRAIT_DECLARATION(t_TYPE, t_TRAIT)
Definition bslmf_nestedtraitdeclaration.h:231
Definition bdlcc_skiplist.h:693
bool isValid() const
Definition bdlcc_skiplist.h:1898
void release()
Release the reference (if any) managed by this SkipListPairHandle.
Definition bdlcc_skiplist.h:1852
void releaseReferenceRaw(SkipList< KEY, DATA > **list, Pair **reference)
Definition bdlcc_skiplist.h:1864
~SkipListPairHandle()
Definition bdlcc_skiplist.h:1834
SkipListPairHandle()
Construct a new PairHandle that does not refer to a pair.
Definition bdlcc_skiplist.h:1805
DATA & data() const
Definition bdlcc_skiplist.h:1889
SkipListPairHandle & operator=(const SkipListPairHandle &rhs)
Definition bdlcc_skiplist.h:1843
const KEY & key() const
Definition bdlcc_skiplist.h:1905
Definition bdlcc_skiplist.h:657
const KEY & key() const
Return a reference to the non-modifiable "key" value of this pair.
Definition bdlcc_skiplist.h:1793
DATA & data() const
Return a reference to the modifiable "data" of this pair.
Definition bdlcc_skiplist.h:1786
Definition bdlcc_skiplist.h:1729
PairFactory(SkipList *)
Create a PairFactory.
Definition bdlcc_skiplist.h:1984
Pair * operator()(Node *node) const
Convert the specified node to a Pair *.
Definition bdlcc_skiplist.h:1991
Definition bdlcc_skiplist.h:1747
PairHandleFactory(SkipList *list)
Create a PairHandleFactory bound to the specified list.
Definition bdlcc_skiplist.h:2003
PairHandle operator()(Node *node) const
Definition bdlcc_skiplist.h:2011
Definition bdlcc_skiplist.h:502
SkipList_DoubleLockGuard(bslmt::Mutex *lock1, bslmt::Mutex *lock2)
Definition bdlcc_skiplist.h:1773
Definition bdlcc_skiplist.h:599
SkipList_NodeCreationHelper(PoolManager *poolManager, Node *node, bslma::Allocator *basicAllocator=0)
Definition bdlcc_skiplist.h:1933
~SkipList_NodeCreationHelper()
Definition bdlcc_skiplist.h:1946
void construct(const KEY &key, const DATA &data)
Definition bdlcc_skiplist.h:1958
Definition bdlcc_skiplist.h:522
SkipList_RandomLevelGenerator()
Construct a thread-aware random-level generator.
int randomLevel()
Return a random integer between 0 and k_MAX_LEVEL.
Definition bdlcc_skiplist.h:783
int find(PairHandle *item, const KEY &key) const
Definition bdlcc_skiplist.h:3511
int findRRaw(Pair **item, const KEY &key) const
Definition bdlcc_skiplist.h:3551
~SkipList()
Definition bdlcc_skiplist.h:2889
void releaseReferenceRaw(const Pair *reference)
Definition bdlcc_skiplist.h:2958
int remove(const Pair *reference)
Definition bdlcc_skiplist.h:3235
int back(PairHandle *back) const
Definition bdlcc_skiplist.h:3350
int skipForward(PairHandle *item) const
Definition bdlcc_skiplist.h:3750
friend bool operator!=(const SkipList< KEY2, DATA2 > &, const SkipList< KEY2, DATA2 > &)
int addUnique(const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3059
int addUniqueRaw(Pair **result, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3070
int skipBackwardRaw(Pair **item) const
Definition bdlcc_skiplist.h:3740
bool isEmpty() const
Return true if this list is empty, and false otherwise.
Definition bdlcc_skiplist.h:3410
int skipForwardRaw(Pair **item) const
Definition bdlcc_skiplist.h:3760
bslma::Allocator * allocator() const
Return the allocator used by this object to supply memory.
Definition bdlcc_skiplist.h:3772
int removeAll(std::vector< PairHandle > *removed)
Definition bdlcc_skiplist.h:3268
void addR(const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3138
SkipList(const SkipList &original, bslma::Allocator *basicAllocator=0)
Definition bdlcc_skiplist.h:2876
int findLowerBoundRRaw(Pair **item, const KEY &key) const
Definition bdlcc_skiplist.h:3604
int nextRaw(Pair **next, const Pair *reference) const
Definition bdlcc_skiplist.h:3686
int addUniqueR(const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3174
void addR(PairHandle *result, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3126
int removeAllRaw(bsl::vector< Pair * > *removed)
Definition bdlcc_skiplist.h:3284
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition bdlcc_skiplist.h:3428
int removeAllRaw(std::vector< Pair * > *removed)
Definition bdlcc_skiplist.h:3291
int length() const
Return the number of items in this list.
Definition bdlcc_skiplist.h:3419
int findLowerBoundRaw(Pair **item, const KEY &key) const
Definition bdlcc_skiplist.h:3577
friend bool operator==(const SkipList< KEY2, DATA2 > &, const SkipList< KEY2, DATA2 > &)
void addAtLevelRawR(Pair **result, int level, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3083
int findUpperBound(PairHandle *item, const KEY &key) const
Definition bdlcc_skiplist.h:3616
int removeAll(bsl::vector< PairHandle > *removed)
Definition bdlcc_skiplist.h:3261
int next(PairHandle *next, const Pair *reference) const
Definition bdlcc_skiplist.h:3669
int findLowerBoundR(PairHandle *item, const KEY &key) const
Definition bdlcc_skiplist.h:3589
int popFront(PairHandle *item=0)
Definition bdlcc_skiplist.h:3197
static int level(const Pair *reference)
Definition bdlcc_skiplist.h:2856
int previous(PairHandle *prevPair, const Pair *reference) const
Definition bdlcc_skiplist.h:3699
SkipList(bslma::Allocator *basicAllocator=0)
Definition bdlcc_skiplist.h:2866
int popFrontRaw(Pair **item)
Definition bdlcc_skiplist.h:3216
int update(const Pair *reference, const KEY &newKey, bool *newFrontFlag=0, bool allowDuplicates=true)
Definition bdlcc_skiplist.h:3309
int findR(PairHandle *item, const KEY &key) const
Definition bdlcc_skiplist.h:3537
SkipListPairHandle< KEY, DATA > PairHandle
Definition bdlcc_skiplist.h:807
int addUniqueRawR(Pair **result, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3184
int addUniqueR(PairHandle *result, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3157
SkipList & operator=(const SkipList &rhs)
Definition bdlcc_skiplist.h:2914
@ RET_INVALID
Definition bdlcc_skiplist.h:801
@ RET_NOT_FOUND
Definition bdlcc_skiplist.h:799
@ RET_SUCCESS
Definition bdlcc_skiplist.h:798
@ e_INVALID
Definition bdlcc_skiplist.h:791
@ BCEC_NOT_FOUND
Definition bdlcc_skiplist.h:795
@ BCEC_INVALID
Definition bdlcc_skiplist.h:797
@ e_NOT_FOUND
Definition bdlcc_skiplist.h:789
@ RET_DUPLICATE
Definition bdlcc_skiplist.h:800
@ BCEC_SUCCESS
Definition bdlcc_skiplist.h:794
@ e_SUCCESS
Definition bdlcc_skiplist.h:788
@ BCEC_DUPLICATE
Definition bdlcc_skiplist.h:796
@ e_DUPLICATE
Definition bdlcc_skiplist.h:790
void add(const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:2980
int addUnique(PairHandle *result, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3043
void add(PairHandle *result, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:2968
void addRawR(Pair **result, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3148
SkipListPair< KEY, DATA > Pair
Definition bdlcc_skiplist.h:806
bool exists(const KEY &key) const
Definition bdlcc_skiplist.h:3369
int addAtLevelUniqueRawR(Pair **result, int level, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3099
Pair * addPairReferenceRaw(const Pair *reference) const
Definition bdlcc_skiplist.h:3341
BSLMF_NESTED_TRAIT_DECLARATION(SkipList, bslma::UsesBslmaAllocator)
void addRaw(Pair **result, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3033
int backRaw(Pair **back) const
Definition bdlcc_skiplist.h:3362
void addAtLevelRaw(Pair **result, int level, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:2990
int findUpperBoundRRaw(Pair **item, const KEY &key) const
Definition bdlcc_skiplist.h:3658
int findLowerBound(PairHandle *item, const KEY &key) const
Definition bdlcc_skiplist.h:3563
int updateR(const Pair *reference, const KEY &newKey, bool *newFrontFlag=0, bool allowDuplicates=true)
Definition bdlcc_skiplist.h:3324
int findUpperBoundR(PairHandle *item, const KEY &key) const
Definition bdlcc_skiplist.h:3643
int findUpperBoundRaw(Pair **item, const KEY &key) const
Definition bdlcc_skiplist.h:3631
int addAtLevelUniqueRaw(Pair **result, int level, const KEY &key, const DATA &data, bool *newFrontFlag=0)
Definition bdlcc_skiplist.h:3006
int removeAll()
Definition bdlcc_skiplist.h:3254
int findRaw(Pair **item, const KEY &key) const
Definition bdlcc_skiplist.h:3525
int skipBackward(PairHandle *item) const
Definition bdlcc_skiplist.h:3730
int frontRaw(Pair **front) const
Definition bdlcc_skiplist.h:3400
int front(PairHandle *front) const
Definition bdlcc_skiplist.h:3386
int previousRaw(Pair **prevPair, const Pair *reference) const
Definition bdlcc_skiplist.h:3718
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2511
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2519
Definition bslstl_vector.h:1025
iterator insert(const_iterator position, const VALUE_TYPE &value)
Definition bslstl_vector.h:3803
void reserve(size_type newCapacity)
Definition bslstl_vector.h:3690
VALUE_TYPE * iterator
Definition bslstl_vector.h:1057
Definition bslma_allocator.h:457
Definition bslmt_lockguard.h:234
Definition bslmt_mutex.h:315
void lock()
Definition bslmt_mutex.h:392
void unlock()
Definition bslmt_mutex.h:410
Definition bsls_atomic.h:743
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLMT_MUTEXASSERT_IS_LOCKED(mutex_p)
Definition bslmt_mutexassert.h:299
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:588
#define BSLS_UTIL_ADDRESSOF(OBJ)
Definition bsls_util.h:289
bsl::ostream & print(bsl::ostream &stream, const TYPE &object, int level=0, int spacesPerLevel=4)
Definition bdlb_printmethods.h:719
Definition bdlcc_boundedqueue.h:270
bool operator!=(const SkipList< KEY, DATA > &lhs, const SkipList< KEY, DATA > &rhs)
bool operator==(const SkipList< KEY, DATA > &lhs, const SkipList< KEY, DATA > &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, const SkipList< KEY, DATA > &list)
Definition bdlb_printmethods.h:283
T::iterator begin(T &container)
Definition bslstl_iterator.h:1495
T::iterator end(T &container)
Definition bslstl_iterator.h:1523
Definition balxml_encoderoptions.h:68
Definition bslmt_barrier.h:344
static bsl::ostream & indent(bsl::ostream &stream, int level, int spacesPerLevel=4)
Definition bdlcc_skiplist.h:482
Node * d_prev_p
Definition bdlcc_skiplist.h:485
Node * d_next_p
Definition bdlcc_skiplist.h:484
This component-private structure is a node in the SkipList.
Definition bdlcc_skiplist.h:477
DATA d_data
Definition bdlcc_skiplist.h:491
SkipList_Node< KEY, DATA > Node
Definition bdlcc_skiplist.h:480
Ptrs d_ptrs[1]
Definition bdlcc_skiplist.h:493
int d_level
Definition bdlcc_skiplist.h:490
KEY d_key
Definition bdlcc_skiplist.h:492
bsls::AtomicInt d_refCount
Definition bdlcc_skiplist.h:489
This component-private utility handles the lock-free pool of list nodes.
Definition bdlcc_skiplist.h:556
static void deallocate(PoolManager *poolManager, void *address)
static PoolManager * createPoolManager(int *objectSizes, int numLevels, bslma::Allocator *basicAllocator)
static void deletePoolManager(bslma::Allocator *basicAllocator, PoolManager *poolManager)
SkipList_PoolManager PoolManager
Definition bdlcc_skiplist.h:559
static void * allocate(PoolManager *poolManager, int level)
Definition bslmf_conditional.h:120
Definition bslmf_issame.h:146
static void copyConstruct(TARGET_TYPE *address, const TARGET_TYPE &original, bslma::Allocator *allocator)
Definition bslalg_scalarprimitives.h:1599
Definition bslma_usesbslmaallocator.h:343
Definition bsls_alignmentfromtype.h:376
std::ptrdiff_t IntPtr
Definition bsls_types.h:130