/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 |