Coverage Report

Created: 2026-05-14 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/duckdb/third_party/skiplist/Node.h
Line
Count
Source
1
/**
2
 * @file
3
 *
4
 * Project: skiplist
5
 *
6
 * Concurrency Tests.
7
 *
8
 * Created by Paul Ross on 03/12/2015.
9
 *
10
 * Copyright (c) 2015-2023 Paul Ross. All rights reserved.
11
 *
12
 * @code
13
 * MIT License
14
 *
15
 * Copyright (c) 2015-2023 Paul Ross
16
 *
17
 * Permission is hereby granted, free of charge, to any person obtaining a copy
18
 * of this software and associated documentation files (the "Software"), to deal
19
 * in the Software without restriction, including without limitation the rights
20
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
 * copies of the Software, and to permit persons to whom the Software is
22
 * furnished to do so, subject to the following conditions:
23
 *
24
 * The above copyright notice and this permission notice shall be included in all
25
 * copies or substantial portions of the Software.
26
 *
27
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
 * SOFTWARE.
34
 * @endcode
35
 */
36
37
#ifndef SkipList_Node_h
38
#define SkipList_Node_h
39
40
#include "IntegrityEnums.h"
41
42
#if __cplusplus < 201103L
43
#define nullptr NULL
44
#endif
45
46
/**************************** Node *********************************/
47
48
/**
49
 * @brief A single node in a Skip List containing a value and references to other downstream Node objects.
50
 *
51
 * @tparam T The type of the Skip List Node values.
52
 * @tparam _Compare A comparison function for type T.
53
 */
54
template <typename T, typename _Compare>
55
class Node {
56
public:
57
  struct _Pool {
58
0
    explicit _Pool(_Compare _cmp) : _compare(_cmp), cache(nullptr) {
59
0
    }
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, float> >)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, double> >)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, short> >)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, int> >)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, long> >)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> >)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> >)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > >)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> >)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, signed char> >)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> >)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::_Pool::_Pool(duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> >)
60
0
    ~_Pool() {
61
0
      delete cache;
62
0
    }
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::_Pool::~_Pool()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::_Pool::~_Pool()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::_Pool::~_Pool()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::_Pool::~_Pool()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::_Pool::~_Pool()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::_Pool::~_Pool()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::_Pool::~_Pool()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::_Pool::~_Pool()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::_Pool::~_Pool()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::_Pool::~_Pool()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::_Pool::~_Pool()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::_Pool::~_Pool()
63
0
    Node *Allocate(const T &value) {
64
0
      if (cache) {
65
0
        Node *result = cache;
66
0
        cache = nullptr;
67
0
        result->Initialize(value);
68
0
        return result;
69
0
      }
70
71
0
      return new Node(value, _compare, *this);
72
0
    }
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::_Pool::Allocate(std::__1::pair<unsigned long, float> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::_Pool::Allocate(std::__1::pair<unsigned long, double> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::_Pool::Allocate(std::__1::pair<unsigned long, short> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::_Pool::Allocate(std::__1::pair<unsigned long, int> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::_Pool::Allocate(std::__1::pair<unsigned long, long> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::_Pool::Allocate(std::__1::pair<unsigned long, duckdb::hugeint_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::_Pool::Allocate(std::__1::pair<unsigned long, duckdb::date_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::_Pool::Allocate(std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::_Pool::Allocate(std::__1::pair<unsigned long, duckdb::dtime_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::_Pool::Allocate(std::__1::pair<unsigned long, signed char> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::_Pool::Allocate(std::__1::pair<unsigned long, duckdb::interval_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::_Pool::Allocate(std::__1::pair<unsigned long, duckdb::string_t> const&)
73
74
0
    T Release(Node *pNode) {
75
0
      T result = pNode->value();
76
0
      std::swap(pNode, cache);
77
0
      delete pNode;
78
0
      return result;
79
0
    }
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::_Pool::Release(duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >*)
80
81
    _Compare _compare;
82
    Node* cache;
83
    pcg32_fast prng;
84
  };
85
86
    Node(const T &value, _Compare _cmp, _Pool &pool);
87
    // Const methods
88
    //
89
    /// Returns the node value
90
0
    const T &value() const { return _value; }
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::value() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::value() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::value() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::value() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::value() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::value() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::value() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::value() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::value() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::value() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::value() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::value() const
91
    // Returns true if the value is present in the skip list from this node onwards.
92
    bool has(const T &value) const;
93
    // Returns the value at the index in the skip list from this node onwards.
94
    // Will return nullptr is not found.
95
    const Node<T, _Compare> *at(size_t idx) const;
96
    // Computes index of the first occurrence of a value
97
    bool index(const T& value, size_t &idx, size_t level) const;
98
    /// Number of linked lists that this node engages in, minimum 1.
99
    size_t height() const { return _nodeRefs.height(); }
100
    // Return the pointer to the next node at level 0
101
    const Node<T, _Compare> *next() const;
102
    // Return the width at given level.
103
    size_t width(size_t level) const;
104
    // Return the node pointer at given level, only used for HeadNode
105
    // integrity checks.
106
    const Node<T, _Compare> *pNode(size_t level) const;
107
108
    // Non-const methods
109
    /// Get a reference to the node references
110
0
    SwappableNodeRefStack<T, _Compare> &nodeRefs() { return _nodeRefs; }
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::nodeRefs()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::nodeRefs()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::nodeRefs()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::nodeRefs()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::nodeRefs()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::nodeRefs()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::nodeRefs()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::nodeRefs()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::nodeRefs()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::nodeRefs()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::nodeRefs()
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::nodeRefs()
111
    /// Get a reference to the node references
112
    const SwappableNodeRefStack<T, _Compare> &nodeRefs() const { return _nodeRefs; }
113
    // Insert a node
114
    Node<T, _Compare> *insert(const T &value);
115
    // Remove a node
116
    Node<T, _Compare> *remove(size_t call_level, const T &value);
117
    // An estimate of the number of bytes used by this node
118
    size_t size_of() const;
119
120
#ifdef INCLUDE_METHODS_THAT_USE_STREAMS
121
    void dotFile(std::ostream &os, size_t suffix = 0) const;
122
    void writeNode(std::ostream &os, size_t suffix = 0) const;
123
#endif // INCLUDE_METHODS_THAT_USE_STREAMS
124
125
    // Integrity checks, returns non-zero on failure
126
    IntegrityCheck lacksIntegrity(size_t headnode_height) const;
127
    IntegrityCheck lacksIntegrityRefsInSet(const std::set<const Node<T, _Compare>*> &nodeSet) const;
128
129
protected:
130
    Node<T, _Compare> *_adjRemoveRefs(size_t level, Node<T, _Compare> *pNode);
131
132
0
  void Initialize(const T &value) {
133
0
    _value = value;
134
0
    _nodeRefs.clear();
135
0
    do {
136
0
      _nodeRefs.push_back(this, _nodeRefs.height() ? 0 : 1);
137
0
    } while (_pool.prng() < _pool.prng.max() / 2);
138
0
  }
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::Initialize(std::__1::pair<unsigned long, float> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::Initialize(std::__1::pair<unsigned long, double> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::Initialize(std::__1::pair<unsigned long, short> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::Initialize(std::__1::pair<unsigned long, int> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::Initialize(std::__1::pair<unsigned long, long> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::Initialize(std::__1::pair<unsigned long, duckdb::hugeint_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::Initialize(std::__1::pair<unsigned long, duckdb::date_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::Initialize(std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::Initialize(std::__1::pair<unsigned long, duckdb::dtime_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::Initialize(std::__1::pair<unsigned long, signed char> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::Initialize(std::__1::pair<unsigned long, duckdb::interval_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::Initialize(std::__1::pair<unsigned long, duckdb::string_t> const&)
139
140
protected:
141
    T _value;
142
    SwappableNodeRefStack<T, _Compare> _nodeRefs;
143
    // Comparison function
144
    _Compare _compare;
145
    _Pool &_pool;
146
private:
147
    // Prevent cctor and operator=
148
    Node(const Node &that);
149
    Node &operator=(const Node &that) const;
150
};
151
152
/**
153
 * Constructor.
154
 * This also creates a SwappableNodeRefStack of random height by tossing a virtual coin.
155
 *
156
 * @tparam T The type of the Skip List Node values.
157
 * @tparam _Compare A comparison function for type T.
158
 * @param value The value of the Node.
159
 * @param _cmp The comparison function.
160
 */
161
template <typename T, typename _Compare>
162
Node<T, _Compare>::Node(const T &value, _Compare _cmp, _Pool &pool) : \
163
0
    _value(value), _compare(_cmp), _pool(pool) {
164
0
    Initialize(value);
165
0
}
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::Node(std::__1::pair<unsigned long, float> const&, duckdb::SkipLess<std::__1::pair<unsigned long, float> >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::_Pool&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::Node(std::__1::pair<unsigned long, double> const&, duckdb::SkipLess<std::__1::pair<unsigned long, double> >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::_Pool&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::Node(std::__1::pair<unsigned long, short> const&, duckdb::SkipLess<std::__1::pair<unsigned long, short> >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::_Pool&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::Node(std::__1::pair<unsigned long, int> const&, duckdb::SkipLess<std::__1::pair<unsigned long, int> >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::_Pool&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::Node(std::__1::pair<unsigned long, long> const&, duckdb::SkipLess<std::__1::pair<unsigned long, long> >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::_Pool&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::Node(std::__1::pair<unsigned long, duckdb::hugeint_t> const&, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::_Pool&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::Node(std::__1::pair<unsigned long, duckdb::date_t> const&, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::_Pool&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::Node(std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > const&, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::_Pool&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::Node(std::__1::pair<unsigned long, duckdb::dtime_t> const&, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::_Pool&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::Node(std::__1::pair<unsigned long, signed char> const&, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::_Pool&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::Node(std::__1::pair<unsigned long, duckdb::interval_t> const&, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::_Pool&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::Node(std::__1::pair<unsigned long, duckdb::string_t> const&, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> >, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::_Pool&)
166
167
/**
168
 * Returns true if the value is present in the skip list from this node onwards.
169
 *
170
 * @tparam T The type of the Skip List Node values.
171
 * @tparam _Compare A comparison function for type T.
172
 * @param value The value to look for.
173
 * @return true if the value is present in the skip list from this node onwards.
174
 */
175
template <typename T, typename _Compare>
176
bool Node<T, _Compare>::has(const T &value) const {
177
    assert(_nodeRefs.height());
178
    assert(value == value); // value can not be NaN for example
179
    // Effectively: if (value > _value) {
180
    if (_compare(_value, value)) {
181
        for (size_t l = _nodeRefs.height(); l-- > 0;) {
182
            if (_nodeRefs[l].pNode && _nodeRefs[l].pNode->has(value)) {
183
                return true;
184
            }
185
        }
186
        return false;
187
    }
188
    // Effectively: return value == _value; // false if value smaller
189
    return !_compare(value, _value) && !_compare(_value, value);
190
}
191
192
/**
193
 * Return a pointer to the n'th node.
194
 * Start (or continue) from the highest level, drop down a level if not found.
195
 * Return nullptr if not found at level 0.
196
 *
197
 * @tparam T The type of the Skip List Node values.
198
 * @tparam _Compare A comparison function for type T.
199
 * @param idx The index from hereon. If zero return this.
200
 * @return Pointer to the Node or nullptr.
201
 */
202
template <typename T, typename _Compare>
203
0
const Node<T, _Compare> *Node<T, _Compare>::at(size_t idx) const {
204
0
    assert(_nodeRefs.height());
205
0
    if (idx == 0) {
206
0
        return this;
207
0
    }
208
0
    for (size_t l = _nodeRefs.height(); l-- > 0;) {
209
0
        if (_nodeRefs[l].pNode && _nodeRefs[l].width <= idx) {
210
0
            return _nodeRefs[l].pNode->at(idx - _nodeRefs[l].width);
211
0
        }
212
0
    }
213
0
    return nullptr;
214
0
}
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::at(unsigned long) const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::at(unsigned long) const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::at(unsigned long) const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::at(unsigned long) const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::at(unsigned long) const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::at(unsigned long) const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::at(unsigned long) const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::at(unsigned long) const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::at(unsigned long) const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::at(unsigned long) const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::at(unsigned long) const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::at(unsigned long) const
215
216
/**
217
 * Computes index of the first occurrence of a value.
218
 *
219
 * @tparam T The type of the Skip List Node values.
220
 * @tparam _Compare A comparison function for type T.
221
 * @param value The value to find.
222
 * @param idx The current index, this will be updated.
223
 * @param level The current level to search from.
224
 * @return true if found, false otherwise.
225
 */
226
template <typename T, typename _Compare>
227
bool Node<T, _Compare>::index(const T& value, size_t &idx, size_t level) const {
228
    assert(_nodeRefs.height());
229
    assert(value == value); // value can not be NaN for example
230
    assert(level < _nodeRefs.height());
231
    // Search has overshot, try again at a lower level.
232
    //if (_value > value) {
233
    if (_compare(value, _value)) {
234
        return false;
235
    }
236
    // First check if we match but we have been approached at a high level
237
    // as there may be an earlier node of the same value but with fewer
238
    // node references. In that case this search has to fail and try at a
239
    // lower level.
240
    // If however the level is 0 and we match then set the idx to 0 to mark us.
241
    // Effectively: if (_value == value) {
242
    if (!_compare(value, _value) && !_compare(_value, value)) {
243
        if (level > 0) {
244
            return false;
245
        }
246
        idx = 0;
247
        return true;
248
    }
249
    // Now work our way down
250
    // NOTE: We initialise l as level + 1 because l-- > 0 will decrement it to
251
    // the correct initial value
252
    for (size_t l = level + 1; l-- > 0;) {
253
        assert(l < _nodeRefs.height());
254
        if (_nodeRefs[l].pNode && _nodeRefs[l].pNode->index(value, idx, l)) {
255
            idx += _nodeRefs[l].width;
256
            return true;
257
        }
258
    }
259
    return false;
260
}
261
262
/**
263
 * Return the pointer to the next node at level 0.
264
 *
265
 * @tparam T The type of the Skip List Node values.
266
 * @tparam _Compare A comparison function for type T.
267
 * @return The next node at level 0.
268
 */
269
template <typename T, typename _Compare>
270
0
const Node<T, _Compare> *Node<T, _Compare>::next() const {
271
0
    assert(_nodeRefs.height());
272
0
    return _nodeRefs[0].pNode;
273
0
}
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::next() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::next() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::next() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::next() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::next() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::next() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::next() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::next() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::next() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::next() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::next() const
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::next() const
274
275
/**
276
 * Return the width at given level.
277
 *
278
 * @tparam T The type of the Skip List Node values.
279
 * @tparam _Compare A comparison function for type T.
280
 * @param level The requested level.
281
 * @return The width.
282
 */
283
template <typename T, typename _Compare>
284
size_t Node<T, _Compare>::width(size_t level) const {
285
    assert(level < _nodeRefs.height());
286
    return _nodeRefs[level].width;
287
}
288
289
/**
290
 * Return the node pointer at given level, only used for HeadNode integrity checks.
291
 *
292
 * @tparam T The type of the Skip List Node values.
293
 * @tparam _Compare A comparison function for type T.
294
 * @param level The requested level.
295
 * @return The Node.
296
 */
297
template <typename T, typename _Compare>
298
const Node<T, _Compare> *Node<T, _Compare>::pNode(size_t level) const {
299
    assert(level < _nodeRefs.height());
300
    return _nodeRefs[level].pNode;
301
}
302
303
/**
304
 * Insert a new node with a value.
305
 *
306
 * @tparam T The type of the Skip List Node values.
307
 * @tparam _Compare A comparison function for type T.
308
 * @param value The value of the Node to insert.
309
 * @return Pointer to the new Node or nullptr on failure.
310
 */
311
template <typename T, typename _Compare>
312
0
Node<T, _Compare> *Node<T, _Compare>::insert(const T &value) {
313
0
    assert(_nodeRefs.height());
314
0
    assert(_nodeRefs.noNodePointerMatches(this));
315
0
    assert(! _nodeRefs.canSwap());
316
0
    assert(value == value); // NaN check for double
317
318
    // Effectively: if (value < _value) {
319
0
    if (_compare(value, _value)) {
320
0
        return nullptr;
321
0
    }
322
    // Recursive search for where to put the node
323
0
    Node<T, _Compare> *pNode = nullptr;
324
0
    size_t level = _nodeRefs.height();
325
    // Effectively: if (value >= _value) {
326
0
    if (! _compare(value, _value)) {
327
0
        for (level = _nodeRefs.height(); level-- > 0;) {
328
0
            if (_nodeRefs[level].pNode) {
329
0
                pNode = _nodeRefs[level].pNode->insert(value);
330
0
                if (pNode) {
331
0
                    break;
332
0
                }
333
0
            }
334
0
        }
335
0
    }
336
    // Effectively: if (! pNode && value >= _value) {
337
0
    if (! pNode && !_compare(value, _value)) {
338
        // Insert new node here
339
0
        pNode = _pool.Allocate(value);
340
0
        level = 0;
341
0
    }
342
0
    assert(pNode); // Should never get here unless a NaN has slipped through
343
    // Adjust references by marching up and recursing back.
344
0
    SwappableNodeRefStack<T, _Compare> &thatRefs = pNode->_nodeRefs;
345
0
    if (! thatRefs.canSwap()) {
346
        // Have an existing node or new node that is all swapped.
347
        // All I need to do is adjust my overshooting nodes and return
348
        // this for the caller to do the same.
349
0
        level = thatRefs.height();
350
0
        while (level < _nodeRefs.height()) {
351
0
            _nodeRefs[level].width += 1;
352
0
            ++level;
353
0
        }
354
        // The caller just has to increment its references that overshoot this
355
0
        assert(! _nodeRefs.canSwap());
356
0
        return this;
357
0
    }
358
    // March upwards
359
0
    if (level < thatRefs.swapLevel()) {
360
0
        assert(level == thatRefs.swapLevel() - 1);
361
        // This will happen when say a 3 high node, A, finds a 2 high
362
        // node, B, that creates a new 2+ high node. A will be at
363
        // level 1 and the new node will have swapLevel == 2 after
364
        // B has swapped.
365
        // Add the level to the accumulator at the next level
366
0
        thatRefs[thatRefs.swapLevel()].width += _nodeRefs[level].width;
367
0
        ++level;
368
0
    }
369
0
    size_t min_height = std::min(_nodeRefs.height(), thatRefs.height());
370
0
    while (level < min_height) {
371
0
        assert(thatRefs.canSwap());
372
0
        assert(level == thatRefs.swapLevel());
373
0
        assert(level < thatRefs.height());
374
0
        assert(_nodeRefs[level].width > 0);
375
0
        assert(thatRefs[level].width > 0);
376
0
        _nodeRefs[level].width -= thatRefs[level].width - 1;
377
0
        assert(_nodeRefs[level].width > 0);
378
0
        thatRefs.swap(_nodeRefs);
379
0
        if (thatRefs.canSwap()) {
380
0
            assert(thatRefs[thatRefs.swapLevel()].width == 0);
381
0
            thatRefs[thatRefs.swapLevel()].width = _nodeRefs[level].width;
382
0
        }
383
0
        ++level;
384
0
    }
385
    // Upwards march complete, now recurse back ('left').
386
0
    if (! thatRefs.canSwap()) {
387
        // All done with pNode locally.
388
0
        assert(level == thatRefs.height());
389
0
        assert(thatRefs.height() <= _nodeRefs.height());
390
0
        assert(level == thatRefs.swapLevel());
391
        // Adjust my overshooting nodes
392
0
        while (level < _nodeRefs.height()) {
393
0
            _nodeRefs[level].width += 1;
394
0
            ++level;
395
0
        }
396
        // The caller just has to increment its references that overshoot this
397
0
        assert(! _nodeRefs.canSwap());
398
0
        pNode = this;
399
0
    }
400
0
    return pNode;
401
0
}
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::insert(std::__1::pair<unsigned long, float> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::insert(std::__1::pair<unsigned long, double> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::insert(std::__1::pair<unsigned long, short> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::insert(std::__1::pair<unsigned long, int> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::insert(std::__1::pair<unsigned long, long> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::insert(std::__1::pair<unsigned long, duckdb::hugeint_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::insert(std::__1::pair<unsigned long, duckdb::date_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::insert(std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::insert(std::__1::pair<unsigned long, duckdb::dtime_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::insert(std::__1::pair<unsigned long, signed char> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::insert(std::__1::pair<unsigned long, duckdb::interval_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::insert(std::__1::pair<unsigned long, duckdb::string_t> const&)
402
403
/**
404
 * Adjust the Node references.
405
 *
406
 * @tparam T The type of the Skip List Node values.
407
 * @tparam _Compare A comparison function for type T.
408
 * @param level The level of the caller's node.
409
 * @param pNode The Node to swap references with.
410
 * @return The Node with swapped references.
411
 */
412
template <typename T, typename _Compare>
413
0
Node<T, _Compare> *Node<T, _Compare>::_adjRemoveRefs(size_t level, Node<T, _Compare> *pNode) {
414
0
    assert(pNode);
415
0
    SwappableNodeRefStack<T, _Compare> &thatRefs = pNode->_nodeRefs;
416
417
0
    assert(pNode != this);
418
0
    if (level < thatRefs.swapLevel()) {
419
0
        assert(level == thatRefs.swapLevel() - 1);
420
0
        ++level;
421
0
    }
422
0
    if (thatRefs.canSwap()) {
423
0
        assert(level == thatRefs.swapLevel());
424
0
        while (level < _nodeRefs.height() && thatRefs.canSwap()) {
425
0
            assert(level == thatRefs.swapLevel());
426
            // Compute the new width for the new node
427
0
            thatRefs[level].width += _nodeRefs[level].width - 1;
428
0
            thatRefs.swap(_nodeRefs);
429
0
            ++level;
430
0
        }
431
0
        assert(thatRefs.canSwap() || thatRefs.allNodePointerMatch(pNode));
432
0
    }
433
    // Decrement my widths as my refs are over the top of the missing pNode.
434
0
    while (level < _nodeRefs.height()) {
435
0
        _nodeRefs[level].width -= 1;
436
0
        ++level;
437
0
        thatRefs.incSwapLevel();
438
0
    }
439
0
    assert(! _nodeRefs.canSwap());
440
0
    return pNode;
441
0
}
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >*)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::_adjRemoveRefs(unsigned long, duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >*)
442
443
/**
444
 * Remove a Node with the given value to be removed.
445
 * The return value must be deleted, the other Nodes have been adjusted as required.
446
 *
447
 * @tparam T The type of the Skip List Node values.
448
 * @tparam _Compare A comparison function for type T.
449
 * @param call_level Level the caller Node is at.
450
 * @param value Value of the detached Node to remove.
451
 * @return A pointer to the Node to be free'd or nullptr on failure.
452
 */
453
template <typename T, typename _Compare>
454
Node<T, _Compare> *Node<T, _Compare>::remove(size_t call_level,
455
0
                         const T &value) {
456
0
    assert(_nodeRefs.height());
457
0
    assert(_nodeRefs.noNodePointerMatches(this));
458
459
0
    Node<T, _Compare> *pNode = nullptr;
460
    // Effectively: if (value >= _value) {
461
0
    if (!_compare(value, _value)) {
462
0
        for (size_t level = call_level + 1; level-- > 0;) {
463
0
            if (_nodeRefs[level].pNode) {
464
                // Make progress to the right
465
0
                pNode = _nodeRefs[level].pNode->remove(level, value);
466
0
                if (pNode) {
467
0
                    return _adjRemoveRefs(level, pNode);
468
0
                }
469
0
            }
470
            // Make progress down
471
0
        }
472
0
    }
473
0
    if (! pNode) { // Base case
474
        // We only admit to being the node to remove if the caller is
475
        // approaching us from level 0. It is entirely likely that
476
        // the same (or an other) caller can see us at a higher level
477
        // but the recursion stack will not have been set up in the correct
478
        // step wise fashion so that the lower level references will
479
        // not be swapped.
480
        // Effectively: if (call_level == 0 && value == _value) {
481
0
        if (call_level == 0 && !_compare(value, _value) && !_compare(_value, value)) {
482
0
            _nodeRefs.resetSwapLevel();
483
0
            return this;
484
0
        }
485
0
    }
486
0
    assert(pNode == nullptr);
487
0
    return nullptr;
488
0
}
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, float>, duckdb::SkipLess<std::__1::pair<unsigned long, float> > >::remove(unsigned long, std::__1::pair<unsigned long, float> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, double>, duckdb::SkipLess<std::__1::pair<unsigned long, double> > >::remove(unsigned long, std::__1::pair<unsigned long, double> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, short>, duckdb::SkipLess<std::__1::pair<unsigned long, short> > >::remove(unsigned long, std::__1::pair<unsigned long, short> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, int>, duckdb::SkipLess<std::__1::pair<unsigned long, int> > >::remove(unsigned long, std::__1::pair<unsigned long, int> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, long>, duckdb::SkipLess<std::__1::pair<unsigned long, long> > >::remove(unsigned long, std::__1::pair<unsigned long, long> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::hugeint_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::hugeint_t> > >::remove(unsigned long, std::__1::pair<unsigned long, duckdb::hugeint_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::date_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::date_t> > >::remove(unsigned long, std::__1::pair<unsigned long, duckdb::date_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> >, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > > >::remove(unsigned long, std::__1::pair<unsigned long, duckdb::timebase_t<1000000l, false> > const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::dtime_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::dtime_t> > >::remove(unsigned long, std::__1::pair<unsigned long, duckdb::dtime_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, signed char>, duckdb::SkipLess<std::__1::pair<unsigned long, signed char> > >::remove(unsigned long, std::__1::pair<unsigned long, signed char> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::interval_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::interval_t> > >::remove(unsigned long, std::__1::pair<unsigned long, duckdb::interval_t> const&)
Unexecuted instantiation: duckdb_skiplistlib::skip_list::Node<std::__1::pair<unsigned long, duckdb::string_t>, duckdb::SkipLess<std::__1::pair<unsigned long, duckdb::string_t> > >::remove(unsigned long, std::__1::pair<unsigned long, duckdb::string_t> const&)
489
490
/*
491
 * This checks the internal consistency of a Node. It returns 0
492
 * if successful, non-zero on error. The tests are:
493
 *
494
 * - Height must be >= 1
495
 * - Height must not exceed HeadNode height.
496
 * - NULL pointer must not have a non-NULL above them.
497
 * - Node pointers must not be self-referential.
498
 */
499
/**
500
 * This checks the internal consistency of a Node. It returns 0
501
 * if successful, non-zero on error. The tests are:
502
 *
503
 * - Height must be >= 1
504
 * - Height must not exceed HeadNode height.
505
 * - NULL pointer must not have a non-NULL above them.
506
 * - Node pointers must not be self-referential.
507
 *
508
 * @tparam T The type of the Skip List Node values.
509
 * @tparam _Compare A comparison function for type T.
510
 * @param headnode_height Height of HeadNode.
511
 * @return An IntegrityCheck enum.
512
 */
513
template <typename T, typename _Compare>
514
IntegrityCheck Node<T, _Compare>::lacksIntegrity(size_t headnode_height) const {
515
    IntegrityCheck result = _nodeRefs.lacksIntegrity();
516
    if (result) {
517
        return result;
518
    }
519
    if (_nodeRefs.height() == 0) {
520
        return NODE_HEIGHT_ZERO;
521
    }
522
    if (_nodeRefs.height() > headnode_height) {
523
        return NODE_HEIGHT_EXCEEDS_HEADNODE;
524
    }
525
    // Test: All nodes above a nullprt must be nullptr
526
    size_t level = 0;
527
    while (level < _nodeRefs.height()) {
528
        if (! _nodeRefs[level].pNode) {
529
            break;
530
        }
531
        ++level;
532
    }
533
    while (level < _nodeRefs.height()) {
534
        if (_nodeRefs[level].pNode) {
535
            return NODE_NON_NULL_AFTER_NULL;
536
        }
537
        ++level;
538
    }
539
    // No reference should be to self.
540
    if (! _nodeRefs.noNodePointerMatches(this)) {
541
        return NODE_SELF_REFERENCE;
542
    }
543
    return INTEGRITY_SUCCESS;
544
}
545
546
/**
547
 * Checks that this Node is in the set held by the HeadNode.
548
 *
549
 * @tparam T The type of the Skip List Node values.
550
 * @tparam _Compare A comparison function for type T.
551
 * @param nodeSet Set of Nodes held by the HeadNode.
552
 * @return An IntegrityCheck enum.
553
 */
554
template <typename T, typename _Compare>
555
IntegrityCheck Node<T, _Compare>::lacksIntegrityRefsInSet(const std::set<const Node<T, _Compare>*> &nodeSet) const {
556
    size_t level = 0;
557
    while (level < _nodeRefs.height()) {
558
        if (nodeSet.count(_nodeRefs[level].pNode) == 0) {
559
            return NODE_REFERENCES_NOT_IN_GLOBAL_SET;
560
        }
561
        ++level;
562
    }
563
    return INTEGRITY_SUCCESS;
564
}
565
566
/**
567
 * Returns an estimate of the memory usage of an instance.
568
 *
569
 * @tparam T The type of the Skip List Node values.
570
 * @tparam _Compare A comparison function for type T.
571
 * @return The memory estimate of this Node.
572
 */
573
template <typename T, typename _Compare>
574
size_t Node<T, _Compare>::size_of() const {
575
    // sizeof(*this) includes the size of _nodeRefs but _nodeRefs.size_of()
576
    // includes sizeof(_nodeRefs) so we need to subtract to avoid double counting
577
    return sizeof(*this) + _nodeRefs.size_of() - sizeof(_nodeRefs);
578
}
579
580
581
#ifdef INCLUDE_METHODS_THAT_USE_STREAMS
582
583
/**
584
 * Writes out this Node address.
585
 *
586
 * @tparam T The type of the Skip List Node values.
587
 * @tparam _Compare A comparison function for type T.
588
 * @param os Where to write.
589
 * @param suffix The suffix (node number).
590
 */
591
template <typename T, typename _Compare>
592
void Node<T, _Compare>::writeNode(std::ostream &os, size_t suffix) const {
593
    os << "\"node";
594
    os << suffix;
595
    os << std::hex << this << std::dec << "\"";
596
}
597
598
/**
599
 * Writes out a fragment of a DOT file representing this Node.
600
 *
601
 * @tparam T The type of the Skip List Node values.
602
 * @tparam _Compare A comparison function for type T.
603
 * @param os Wheere to write.
604
 * @param suffix The node number.
605
 */
606
template <typename T, typename _Compare>
607
void Node<T, _Compare>::dotFile(std::ostream &os, size_t suffix) const {
608
    assert(_nodeRefs.height());
609
    writeNode(os, suffix);
610
    os << " [" << std::endl;
611
    os << "label = \"";
612
    for (size_t level = _nodeRefs.height(); level-- > 0;) {
613
        os << " { <w" << level + 1 << "> " << _nodeRefs[level].width;
614
        os << " | <f" << level + 1 << "> ";
615
        os << std::hex << _nodeRefs[level].pNode << std::dec;
616
        os << " }";
617
        os << " |";
618
    }
619
    os << " <f0> " << _value << "\"" << std::endl;
620
    os << "shape = \"record\"" << std::endl;
621
    os << "];" << std::endl;
622
    // Now edges
623
    for (size_t level = 0; level < _nodeRefs.height(); ++level) {
624
        writeNode(os, suffix);
625
        os << ":f" << level + 1 << " -> ";
626
        _nodeRefs[level].pNode->writeNode(os, suffix);
627
        //        writeNode(os, suffix);
628
        //        os << ":f" << i + 1 << " [];" << std::endl;
629
        os << ":w" << level + 1 << " [];" << std::endl;
630
    }
631
    assert(_nodeRefs.height());
632
    if (_nodeRefs[0].pNode) {
633
        _nodeRefs[0].pNode->dotFile(os, suffix);
634
    }
635
}
636
637
#endif // INCLUDE_METHODS_THAT_USE_STREAMS
638
639
/************************** END: Node *******************************/
640
641
#endif // SkipList_Node_h