Coverage Report

Created: 2026-10-28 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/text/qfragmentmap_p.h
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4
#ifndef QFRAGMENTMAP_P_H
5
#define QFRAGMENTMAP_P_H
6
7
//
8
//  W A R N I N G
9
//  -------------
10
//
11
// This file is not part of the Qt API.  It exists purely as an
12
// implementation detail.  This header file may change from version to
13
// version without notice, or even be removed.
14
//
15
// We mean it.
16
//
17
18
#include <QtGui/private/qtguiglobal_p.h>
19
#include <stdlib.h>
20
#include <private/qtools_p.h>
21
22
QT_BEGIN_NAMESPACE
23
24
25
template <int N = 1>
26
class QFragment
27
{
28
public:
29
    quint32 parent;
30
    quint32 left;
31
    quint32 right;
32
    quint32 color;
33
    quint32 size_left_array[N];
34
    quint32 size_array[N];
35
    enum {size_array_max = N };
36
};
37
38
template <class Fragment>
39
class QFragmentMapData
40
{
41
    enum Color { Red, Black };
42
public:
43
    QFragmentMapData();
44
    ~QFragmentMapData();
45
46
    void init();
47
48
    class Header
49
    {
50
    public:
51
        quint32 root; // this relies on being at the same position as parent in the fragment struct
52
        quint32 tag;
53
        quint32 freelist;
54
        quint32 node_count;
55
        quint32 allocated;
56
    };
57
58
59
    enum {fragmentSize = sizeof(Fragment) };
60
61
62
    int length(uint field = 0) const;
63
64
65
8.78M
    inline Fragment *fragment(uint index) {
66
8.78M
        return (fragments + index);
67
8.78M
    }
QFragmentMapData<QTextBlockData>::fragment(unsigned int)
Line
Count
Source
65
7.52M
    inline Fragment *fragment(uint index) {
66
7.52M
        return (fragments + index);
67
7.52M
    }
QFragmentMapData<QTextFragmentData>::fragment(unsigned int)
Line
Count
Source
65
1.26M
    inline Fragment *fragment(uint index) {
66
1.26M
        return (fragments + index);
67
1.26M
    }
68
234M
    inline const Fragment *fragment(uint index) const {
69
234M
        return (fragments + index);
70
234M
    }
QFragmentMapData<QTextFragmentData>::fragment(unsigned int) const
Line
Count
Source
68
127M
    inline const Fragment *fragment(uint index) const {
69
127M
        return (fragments + index);
70
127M
    }
QFragmentMapData<QTextBlockData>::fragment(unsigned int) const
Line
Count
Source
68
107M
    inline const Fragment *fragment(uint index) const {
69
107M
        return (fragments + index);
70
107M
    }
71
72
73
67.7M
    inline Fragment &F(uint index) { return fragments[index] ; }
QFragmentMapData<QTextFragmentData>::F(unsigned int)
Line
Count
Source
73
39.3M
    inline Fragment &F(uint index) { return fragments[index] ; }
QFragmentMapData<QTextBlockData>::F(unsigned int)
Line
Count
Source
73
28.4M
    inline Fragment &F(uint index) { return fragments[index] ; }
74
52.3M
    inline const Fragment &F(uint index) const { return fragments[index] ; }
QFragmentMapData<QTextFragmentData>::F(unsigned int) const
Line
Count
Source
74
27.7M
    inline const Fragment &F(uint index) const { return fragments[index] ; }
QFragmentMapData<QTextBlockData>::F(unsigned int) const
Line
Count
Source
74
24.6M
    inline const Fragment &F(uint index) const { return fragments[index] ; }
75
76
    inline bool isRoot(uint index) const {
77
        return !fragment(index)->parent;
78
    }
79
80
5.97M
    inline uint position(uint node, uint field = 0) const {
81
5.97M
        Q_ASSERT(field < Fragment::size_array_max);
82
5.97M
        const Fragment *f = fragment(node);
83
5.97M
        uint offset = f->size_left_array[field];
84
32.8M
        while (f->parent) {
85
26.8M
            uint p = f->parent;
86
26.8M
            f = fragment(p);
87
26.8M
            if (f->right == node)
88
20.0M
                offset += f->size_left_array[field] + f->size_array[field];
89
26.8M
            node = p;
90
26.8M
        }
91
5.97M
        return offset;
92
5.97M
    }
QFragmentMapData<QTextFragmentData>::position(unsigned int, unsigned int) const
Line
Count
Source
80
684k
    inline uint position(uint node, uint field = 0) const {
81
684k
        Q_ASSERT(field < Fragment::size_array_max);
82
684k
        const Fragment *f = fragment(node);
83
684k
        uint offset = f->size_left_array[field];
84
6.10M
        while (f->parent) {
85
5.42M
            uint p = f->parent;
86
5.42M
            f = fragment(p);
87
5.42M
            if (f->right == node)
88
5.42M
                offset += f->size_left_array[field] + f->size_array[field];
89
5.42M
            node = p;
90
5.42M
        }
91
684k
        return offset;
92
684k
    }
QFragmentMapData<QTextBlockData>::position(unsigned int, unsigned int) const
Line
Count
Source
80
5.28M
    inline uint position(uint node, uint field = 0) const {
81
5.28M
        Q_ASSERT(field < Fragment::size_array_max);
82
5.28M
        const Fragment *f = fragment(node);
83
5.28M
        uint offset = f->size_left_array[field];
84
26.7M
        while (f->parent) {
85
21.4M
            uint p = f->parent;
86
21.4M
            f = fragment(p);
87
21.4M
            if (f->right == node)
88
14.6M
                offset += f->size_left_array[field] + f->size_array[field];
89
21.4M
            node = p;
90
21.4M
        }
91
5.28M
        return offset;
92
5.28M
    }
93
3.17M
    inline uint sizeRight(uint node, uint field = 0) const {
94
3.17M
        Q_ASSERT(field < Fragment::size_array_max);
95
3.17M
        uint sr = 0;
96
3.17M
        const Fragment *f = fragment(node);
97
3.17M
        node = f->right;
98
26.5M
        while (node) {
99
23.3M
            f = fragment(node);
100
23.3M
            sr += f->size_left_array[field] + f->size_array[field];
101
23.3M
            node = f->right;
102
23.3M
        }
103
3.17M
        return sr;
104
3.17M
    }
QFragmentMapData<QTextFragmentData>::sizeRight(unsigned int, unsigned int) const
Line
Count
Source
93
1.60M
    inline uint sizeRight(uint node, uint field = 0) const {
94
1.60M
        Q_ASSERT(field < Fragment::size_array_max);
95
1.60M
        uint sr = 0;
96
1.60M
        const Fragment *f = fragment(node);
97
1.60M
        node = f->right;
98
12.1M
        while (node) {
99
10.4M
            f = fragment(node);
100
10.4M
            sr += f->size_left_array[field] + f->size_array[field];
101
10.4M
            node = f->right;
102
10.4M
        }
103
1.60M
        return sr;
104
1.60M
    }
QFragmentMapData<QTextBlockData>::sizeRight(unsigned int, unsigned int) const
Line
Count
Source
93
1.56M
    inline uint sizeRight(uint node, uint field = 0) const {
94
1.56M
        Q_ASSERT(field < Fragment::size_array_max);
95
1.56M
        uint sr = 0;
96
1.56M
        const Fragment *f = fragment(node);
97
1.56M
        node = f->right;
98
14.4M
        while (node) {
99
12.8M
            f = fragment(node);
100
12.8M
            sr += f->size_left_array[field] + f->size_array[field];
101
12.8M
            node = f->right;
102
12.8M
        }
103
1.56M
        return sr;
104
1.56M
    }
105
98.4M
    inline uint sizeLeft(uint node, uint field = 0) const {
106
98.4M
        Q_ASSERT(field < Fragment::size_array_max);
107
98.4M
        return fragment(node)->size_left_array[field];
108
98.4M
    }
QFragmentMapData<QTextFragmentData>::sizeLeft(unsigned int, unsigned int) const
Line
Count
Source
105
63.3M
    inline uint sizeLeft(uint node, uint field = 0) const {
106
        Q_ASSERT(field < Fragment::size_array_max);
107
63.3M
        return fragment(node)->size_left_array[field];
108
63.3M
    }
QFragmentMapData<QTextBlockData>::sizeLeft(unsigned int, unsigned int) const
Line
Count
Source
105
35.0M
    inline uint sizeLeft(uint node, uint field = 0) const {
106
        Q_ASSERT(field < Fragment::size_array_max);
107
35.0M
        return fragment(node)->size_left_array[field];
108
35.0M
    }
109
110
111
64.2M
    inline uint size(uint node, uint field = 0) const {
112
64.2M
        Q_ASSERT(field < Fragment::size_array_max);
113
64.2M
        return fragment(node)->size_array[field];
114
64.2M
    }
QFragmentMapData<QTextFragmentData>::size(unsigned int, unsigned int) const
Line
Count
Source
111
37.3M
    inline uint size(uint node, uint field = 0) const {
112
        Q_ASSERT(field < Fragment::size_array_max);
113
37.3M
        return fragment(node)->size_array[field];
114
37.3M
    }
QFragmentMapData<QTextBlockData>::size(unsigned int, unsigned int) const
Line
Count
Source
111
26.8M
    inline uint size(uint node, uint field = 0) const {
112
        Q_ASSERT(field < Fragment::size_array_max);
113
26.8M
        return fragment(node)->size_array[field];
114
26.8M
    }
115
116
107k
    inline void setSize(uint node, int new_size, uint field = 0) {
117
107k
        Q_ASSERT(field < Fragment::size_array_max);
118
107k
        Fragment *f = fragment(node);
119
107k
        int diff = new_size - f->size_array[field];
120
107k
        f->size_array[field] = new_size;
121
659k
        while (f->parent) {
122
552k
            uint p = f->parent;
123
552k
            f = fragment(p);
124
552k
            if (f->left == node)
125
0
                f->size_left_array[field] += diff;
126
552k
            node = p;
127
552k
        }
128
107k
    }
QFragmentMapData<QTextBlockData>::setSize(unsigned int, int, unsigned int)
Line
Count
Source
116
107k
    inline void setSize(uint node, int new_size, uint field = 0) {
117
107k
        Q_ASSERT(field < Fragment::size_array_max);
118
107k
        Fragment *f = fragment(node);
119
107k
        int diff = new_size - f->size_array[field];
120
107k
        f->size_array[field] = new_size;
121
659k
        while (f->parent) {
122
552k
            uint p = f->parent;
123
552k
            f = fragment(p);
124
552k
            if (f->left == node)
125
0
                f->size_left_array[field] += diff;
126
552k
            node = p;
127
552k
        }
128
107k
    }
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::setSize(unsigned int, int, unsigned int)
129
130
131
    uint findNode(int k, uint field = 0) const;
132
133
    uint insert_single(int key, uint length);
134
    uint erase_single(uint f);
135
136
67.4k
    uint minimum(uint n) const {
137
114k
        while (n && fragment(n)->left)
138
47.0k
            n = fragment(n)->left;
139
67.4k
        return n;
140
67.4k
    }
QFragmentMapData<QTextFragmentData>::minimum(unsigned int) const
Line
Count
Source
136
22.4k
    uint minimum(uint n) const {
137
55.8k
        while (n && fragment(n)->left)
138
33.4k
            n = fragment(n)->left;
139
22.4k
        return n;
140
22.4k
    }
QFragmentMapData<QTextBlockData>::minimum(unsigned int) const
Line
Count
Source
136
44.9k
    uint minimum(uint n) const {
137
58.5k
        while (n && fragment(n)->left)
138
13.6k
            n = fragment(n)->left;
139
44.9k
        return n;
140
44.9k
    }
141
142
0
    uint maximum(uint n) const {
143
0
        while (n && fragment(n)->right)
144
0
            n = fragment(n)->right;
145
0
        return n;
146
0
    }
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::maximum(unsigned int) const
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::maximum(unsigned int) const
147
148
    uint next(uint n) const;
149
    uint previous(uint n) const;
150
151
10.7M
    inline uint root() const {
152
10.7M
        Q_ASSERT(!head->root || !fragment(head->root)->parent);
153
10.7M
        return head->root;
154
10.7M
    }
QFragmentMapData<QTextFragmentData>::root() const
Line
Count
Source
151
6.73M
    inline uint root() const {
152
        Q_ASSERT(!head->root || !fragment(head->root)->parent);
153
6.73M
        return head->root;
154
6.73M
    }
QFragmentMapData<QTextBlockData>::root() const
Line
Count
Source
151
4.05M
    inline uint root() const {
152
        Q_ASSERT(!head->root || !fragment(head->root)->parent);
153
4.05M
        return head->root;
154
4.05M
    }
155
    inline void setRoot(uint new_root) {
156
        Q_ASSERT(!head->root || !fragment(new_root)->parent);
157
        head->root = new_root;
158
    }
159
160
3.46M
    inline bool isValid(uint n) const {
161
3.46M
        return n > 0 && n != head->freelist;
162
3.46M
    }
163
164
    union {
165
        Header *head;
166
        Fragment *fragments;
167
    };
168
169
private:
170
171
    void rotateLeft(uint x);
172
    void rotateRight(uint x);
173
    void rebalance(uint x);
174
    void removeAndRebalance(uint z);
175
176
    uint createFragment();
177
    void freeFragment(uint f);
178
179
};
180
181
template <class Fragment>
182
QFragmentMapData<Fragment>::QFragmentMapData()
183
44.9k
    : fragments(nullptr)
184
44.9k
{
185
44.9k
    init();
186
44.9k
}
QFragmentMapData<QTextFragmentData>::QFragmentMapData()
Line
Count
Source
183
22.4k
    : fragments(nullptr)
184
22.4k
{
185
22.4k
    init();
186
22.4k
}
QFragmentMapData<QTextBlockData>::QFragmentMapData()
Line
Count
Source
183
22.4k
    : fragments(nullptr)
184
22.4k
{
185
22.4k
    init();
186
22.4k
}
187
188
template <class Fragment>
189
void QFragmentMapData<Fragment>::init()
190
44.9k
{
191
    // the following code will realloc an existing fragment or create a new one.
192
    // it will also ignore errors when shrinking an existing fragment.
193
44.9k
    Fragment *newFragments = (Fragment *)realloc(fragments, 64*fragmentSize);
194
44.9k
    if (newFragments) {
195
44.9k
        fragments = newFragments;
196
44.9k
        head->allocated = 64;
197
44.9k
    }
198
44.9k
    Q_CHECK_PTR(fragments);
199
200
44.9k
    head->tag = (((quint32)'p') << 24) | (((quint32)'m') << 16) | (((quint32)'a') << 8) | 'p'; //TAG('p', 'm', 'a', 'p');
201
44.9k
    head->root = 0;
202
44.9k
    head->freelist = 1;
203
44.9k
    head->node_count = 0;
204
    // mark all items to the right as unused
205
44.9k
    F(head->freelist).right = 0;
206
44.9k
}
QFragmentMapData<QTextFragmentData>::init()
Line
Count
Source
190
22.4k
{
191
    // the following code will realloc an existing fragment or create a new one.
192
    // it will also ignore errors when shrinking an existing fragment.
193
22.4k
    Fragment *newFragments = (Fragment *)realloc(fragments, 64*fragmentSize);
194
22.4k
    if (newFragments) {
195
22.4k
        fragments = newFragments;
196
22.4k
        head->allocated = 64;
197
22.4k
    }
198
22.4k
    Q_CHECK_PTR(fragments);
199
200
22.4k
    head->tag = (((quint32)'p') << 24) | (((quint32)'m') << 16) | (((quint32)'a') << 8) | 'p'; //TAG('p', 'm', 'a', 'p');
201
22.4k
    head->root = 0;
202
22.4k
    head->freelist = 1;
203
22.4k
    head->node_count = 0;
204
    // mark all items to the right as unused
205
22.4k
    F(head->freelist).right = 0;
206
22.4k
}
QFragmentMapData<QTextBlockData>::init()
Line
Count
Source
190
22.4k
{
191
    // the following code will realloc an existing fragment or create a new one.
192
    // it will also ignore errors when shrinking an existing fragment.
193
22.4k
    Fragment *newFragments = (Fragment *)realloc(fragments, 64*fragmentSize);
194
22.4k
    if (newFragments) {
195
22.4k
        fragments = newFragments;
196
22.4k
        head->allocated = 64;
197
22.4k
    }
198
22.4k
    Q_CHECK_PTR(fragments);
199
200
22.4k
    head->tag = (((quint32)'p') << 24) | (((quint32)'m') << 16) | (((quint32)'a') << 8) | 'p'; //TAG('p', 'm', 'a', 'p');
201
22.4k
    head->root = 0;
202
22.4k
    head->freelist = 1;
203
22.4k
    head->node_count = 0;
204
    // mark all items to the right as unused
205
22.4k
    F(head->freelist).right = 0;
206
22.4k
}
207
208
template <class Fragment>
209
QFragmentMapData<Fragment>::~QFragmentMapData()
210
44.9k
{
211
44.9k
    free(fragments);
212
44.9k
}
QFragmentMapData<QTextFragmentData>::~QFragmentMapData()
Line
Count
Source
210
22.4k
{
211
22.4k
    free(fragments);
212
22.4k
}
QFragmentMapData<QTextBlockData>::~QFragmentMapData()
Line
Count
Source
210
22.4k
{
211
22.4k
    free(fragments);
212
22.4k
}
213
214
template <class Fragment>
215
uint QFragmentMapData<Fragment>::createFragment()
216
621k
{
217
621k
    Q_ASSERT(head->freelist <= head->allocated);
218
219
621k
    uint freePos = head->freelist;
220
621k
    if (freePos == head->allocated) {
221
        // need to create some free space
222
3.34k
        auto blockInfo = qCalculateGrowingBlockSize(freePos + 1, fragmentSize);
223
3.34k
        Fragment *newFragments = (Fragment *)realloc(fragments, blockInfo.size);
224
3.34k
        Q_CHECK_PTR(newFragments);
225
3.34k
        fragments = newFragments;
226
3.34k
        head->allocated = quint32(blockInfo.elementCount);
227
3.34k
        F(freePos).right = 0;
228
3.34k
    }
229
230
621k
    uint nextPos = F(freePos).right;
231
621k
    if (!nextPos) {
232
621k
        nextPos = freePos+1;
233
621k
        if (nextPos < head->allocated)
234
618k
            F(nextPos).right = 0;
235
621k
    }
236
237
621k
    head->freelist = nextPos;
238
239
621k
    ++head->node_count;
240
241
621k
    return freePos;
242
621k
}
QFragmentMapData<QTextFragmentData>::createFragment()
Line
Count
Source
216
364k
{
217
364k
    Q_ASSERT(head->freelist <= head->allocated);
218
219
364k
    uint freePos = head->freelist;
220
364k
    if (freePos == head->allocated) {
221
        // need to create some free space
222
1.94k
        auto blockInfo = qCalculateGrowingBlockSize(freePos + 1, fragmentSize);
223
1.94k
        Fragment *newFragments = (Fragment *)realloc(fragments, blockInfo.size);
224
1.94k
        Q_CHECK_PTR(newFragments);
225
1.94k
        fragments = newFragments;
226
1.94k
        head->allocated = quint32(blockInfo.elementCount);
227
1.94k
        F(freePos).right = 0;
228
1.94k
    }
229
230
364k
    uint nextPos = F(freePos).right;
231
364k
    if (!nextPos) {
232
364k
        nextPos = freePos+1;
233
364k
        if (nextPos < head->allocated)
234
362k
            F(nextPos).right = 0;
235
364k
    }
236
237
364k
    head->freelist = nextPos;
238
239
364k
    ++head->node_count;
240
241
364k
    return freePos;
242
364k
}
QFragmentMapData<QTextBlockData>::createFragment()
Line
Count
Source
216
257k
{
217
257k
    Q_ASSERT(head->freelist <= head->allocated);
218
219
257k
    uint freePos = head->freelist;
220
257k
    if (freePos == head->allocated) {
221
        // need to create some free space
222
1.40k
        auto blockInfo = qCalculateGrowingBlockSize(freePos + 1, fragmentSize);
223
1.40k
        Fragment *newFragments = (Fragment *)realloc(fragments, blockInfo.size);
224
1.40k
        Q_CHECK_PTR(newFragments);
225
1.40k
        fragments = newFragments;
226
1.40k
        head->allocated = quint32(blockInfo.elementCount);
227
1.40k
        F(freePos).right = 0;
228
1.40k
    }
229
230
257k
    uint nextPos = F(freePos).right;
231
257k
    if (!nextPos) {
232
257k
        nextPos = freePos+1;
233
257k
        if (nextPos < head->allocated)
234
255k
            F(nextPos).right = 0;
235
257k
    }
236
237
257k
    head->freelist = nextPos;
238
239
257k
    ++head->node_count;
240
241
257k
    return freePos;
242
257k
}
243
244
template <class Fragment>
245
void QFragmentMapData<Fragment>::freeFragment(uint i)
246
0
{
247
0
    F(i).right = head->freelist;
248
0
    head->freelist = i;
249
250
0
    --head->node_count;
251
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::freeFragment(unsigned int)
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::freeFragment(unsigned int)
252
253
254
template <class Fragment>
255
3.19M
uint QFragmentMapData<Fragment>::next(uint n) const {
256
3.19M
    Q_ASSERT(n);
257
3.19M
    if (F(n).right) {
258
1.43M
        n = F(n).right;
259
2.45M
        while (F(n).left)
260
1.01M
            n = F(n).left;
261
1.75M
    } else {
262
1.75M
        uint y = F(n).parent;
263
2.99M
        while (F(n).parent && n == F(y).right) {
264
1.24M
            n = y;
265
1.24M
            y = F(y).parent;
266
1.24M
        }
267
1.75M
        n = y;
268
1.75M
    }
269
3.19M
    return n;
270
3.19M
}
QFragmentMapData<QTextBlockData>::next(unsigned int) const
Line
Count
Source
255
2.16M
uint QFragmentMapData<Fragment>::next(uint n) const {
256
2.16M
    Q_ASSERT(n);
257
2.16M
    if (F(n).right) {
258
1.08M
        n = F(n).right;
259
1.79M
        while (F(n).left)
260
703k
            n = F(n).left;
261
1.08M
    } else {
262
1.08M
        uint y = F(n).parent;
263
1.97M
        while (F(n).parent && n == F(y).right) {
264
890k
            n = y;
265
890k
            y = F(y).parent;
266
890k
        }
267
1.08M
        n = y;
268
1.08M
    }
269
2.16M
    return n;
270
2.16M
}
QFragmentMapData<QTextFragmentData>::next(unsigned int) const
Line
Count
Source
255
1.02M
uint QFragmentMapData<Fragment>::next(uint n) const {
256
1.02M
    Q_ASSERT(n);
257
1.02M
    if (F(n).right) {
258
346k
        n = F(n).right;
259
660k
        while (F(n).left)
260
314k
            n = F(n).left;
261
675k
    } else {
262
675k
        uint y = F(n).parent;
263
1.02M
        while (F(n).parent && n == F(y).right) {
264
350k
            n = y;
265
350k
            y = F(y).parent;
266
350k
        }
267
675k
        n = y;
268
675k
    }
269
1.02M
    return n;
270
1.02M
}
271
272
template <class Fragment>
273
576k
uint QFragmentMapData<Fragment>::previous(uint n) const {
274
576k
    if (!n)
275
0
        return maximum(root());
276
277
576k
    if (F(n).left) {
278
258k
        n = F(n).left;
279
439k
        while (F(n).right)
280
181k
            n = F(n).right;
281
318k
    } else {
282
318k
        uint y = F(n).parent;
283
601k
        while (F(n).parent && n == F(y).left) {
284
282k
            n = y;
285
282k
            y = F(y).parent;
286
282k
        }
287
318k
        n = y;
288
318k
    }
289
576k
    return n;
290
576k
}
QFragmentMapData<QTextFragmentData>::previous(unsigned int) const
Line
Count
Source
273
107k
uint QFragmentMapData<Fragment>::previous(uint n) const {
274
107k
    if (!n)
275
0
        return maximum(root());
276
277
107k
    if (F(n).left) {
278
27.8k
        n = F(n).left;
279
27.8k
        while (F(n).right)
280
0
            n = F(n).right;
281
79.3k
    } else {
282
79.3k
        uint y = F(n).parent;
283
158k
        while (F(n).parent && n == F(y).left) {
284
79.3k
            n = y;
285
79.3k
            y = F(y).parent;
286
79.3k
        }
287
79.3k
        n = y;
288
79.3k
    }
289
107k
    return n;
290
107k
}
QFragmentMapData<QTextBlockData>::previous(unsigned int) const
Line
Count
Source
273
469k
uint QFragmentMapData<Fragment>::previous(uint n) const {
274
469k
    if (!n)
275
0
        return maximum(root());
276
277
469k
    if (F(n).left) {
278
230k
        n = F(n).left;
279
411k
        while (F(n).right)
280
181k
            n = F(n).right;
281
239k
    } else {
282
239k
        uint y = F(n).parent;
283
442k
        while (F(n).parent && n == F(y).left) {
284
203k
            n = y;
285
203k
            y = F(y).parent;
286
203k
        }
287
239k
        n = y;
288
239k
    }
289
469k
    return n;
290
469k
}
291
292
293
/*
294
     x              y
295
      \            / \
296
       y    -->   x   b
297
      / \          \
298
     a   b          a
299
*/
300
template <class Fragment>
301
void QFragmentMapData<Fragment>::rotateLeft(uint x)
302
495k
{
303
495k
    uint p = F(x).parent;
304
495k
    uint y = F(x).right;
305
306
307
495k
    if (y) {
308
495k
        F(x).right = F(y).left;
309
495k
        if (F(y).left)
310
219k
            F(F(y).left).parent = x;
311
495k
        F(y).left = x;
312
495k
        F(y).parent = p;
313
495k
    } else {
314
0
        F(x).right = 0;
315
0
    }
316
495k
    if (!p) {
317
24.6k
        Q_ASSERT(head->root == x);
318
24.6k
        head->root = y;
319
24.6k
    }
320
470k
    else if (x == F(p).left)
321
160k
        F(p).left = y;
322
309k
    else
323
309k
        F(p).right = y;
324
495k
    F(x).parent = y;
325
1.40M
    for (uint field = 0; field < Fragment::size_array_max; ++field)
326
906k
        F(y).size_left_array[field] += F(x).size_left_array[field] + F(x).size_array[field];
327
495k
}
QFragmentMapData<QTextFragmentData>::rotateLeft(unsigned int)
Line
Count
Source
302
289k
{
303
289k
    uint p = F(x).parent;
304
289k
    uint y = F(x).right;
305
306
307
289k
    if (y) {
308
289k
        F(x).right = F(y).left;
309
289k
        if (F(y).left)
310
128k
            F(F(y).left).parent = x;
311
289k
        F(y).left = x;
312
289k
        F(y).parent = p;
313
289k
    } else {
314
0
        F(x).right = 0;
315
0
    }
316
289k
    if (!p) {
317
11.0k
        Q_ASSERT(head->root == x);
318
11.0k
        head->root = y;
319
11.0k
    }
320
278k
    else if (x == F(p).left)
321
160k
        F(p).left = y;
322
117k
    else
323
117k
        F(p).right = y;
324
289k
    F(x).parent = y;
325
578k
    for (uint field = 0; field < Fragment::size_array_max; ++field)
326
289k
        F(y).size_left_array[field] += F(x).size_left_array[field] + F(x).size_array[field];
327
289k
}
QFragmentMapData<QTextBlockData>::rotateLeft(unsigned int)
Line
Count
Source
302
205k
{
303
205k
    uint p = F(x).parent;
304
205k
    uint y = F(x).right;
305
306
307
205k
    if (y) {
308
205k
        F(x).right = F(y).left;
309
205k
        if (F(y).left)
310
90.5k
            F(F(y).left).parent = x;
311
205k
        F(y).left = x;
312
205k
        F(y).parent = p;
313
205k
    } else {
314
0
        F(x).right = 0;
315
0
    }
316
205k
    if (!p) {
317
13.6k
        Q_ASSERT(head->root == x);
318
13.6k
        head->root = y;
319
13.6k
    }
320
192k
    else if (x == F(p).left)
321
0
        F(p).left = y;
322
192k
    else
323
192k
        F(p).right = y;
324
205k
    F(x).parent = y;
325
823k
    for (uint field = 0; field < Fragment::size_array_max; ++field)
326
617k
        F(y).size_left_array[field] += F(x).size_left_array[field] + F(x).size_array[field];
327
205k
}
328
329
330
/*
331
         x          y
332
        /          / \
333
       y    -->   a   x
334
      / \            /
335
     a   b          b
336
*/
337
template <class Fragment>
338
void QFragmentMapData<Fragment>::rotateRight(uint x)
339
160k
{
340
160k
    uint y = F(x).left;
341
160k
    uint p = F(x).parent;
342
343
160k
    if (y) {
344
160k
        F(x).left = F(y).right;
345
160k
        if (F(y).right)
346
0
            F(F(y).right).parent = x;
347
160k
        F(y).right = x;
348
160k
        F(y).parent = p;
349
160k
    } else {
350
0
        F(x).left = 0;
351
0
    }
352
160k
    if (!p) {
353
7.76k
        Q_ASSERT(head->root == x);
354
7.76k
        head->root = y;
355
7.76k
    }
356
153k
    else if (x == F(p).right)
357
153k
        F(p).right = y;
358
0
    else
359
0
        F(p).left = y;
360
160k
    F(x).parent = y;
361
321k
    for (uint field = 0; field < Fragment::size_array_max; ++field)
362
160k
        F(x).size_left_array[field] -= F(y).size_left_array[field] + F(y).size_array[field];
363
160k
}
QFragmentMapData<QTextFragmentData>::rotateRight(unsigned int)
Line
Count
Source
339
160k
{
340
160k
    uint y = F(x).left;
341
160k
    uint p = F(x).parent;
342
343
160k
    if (y) {
344
160k
        F(x).left = F(y).right;
345
160k
        if (F(y).right)
346
0
            F(F(y).right).parent = x;
347
160k
        F(y).right = x;
348
160k
        F(y).parent = p;
349
160k
    } else {
350
0
        F(x).left = 0;
351
0
    }
352
160k
    if (!p) {
353
7.76k
        Q_ASSERT(head->root == x);
354
7.76k
        head->root = y;
355
7.76k
    }
356
153k
    else if (x == F(p).right)
357
153k
        F(p).right = y;
358
0
    else
359
0
        F(p).left = y;
360
160k
    F(x).parent = y;
361
321k
    for (uint field = 0; field < Fragment::size_array_max; ++field)
362
160k
        F(x).size_left_array[field] -= F(y).size_left_array[field] + F(y).size_array[field];
363
160k
}
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::rotateRight(unsigned int)
364
365
366
template <class Fragment>
367
void QFragmentMapData<Fragment>::rebalance(uint x)
368
621k
{
369
621k
    F(x).color = Red;
370
371
1.59M
    while (F(x).parent && F(F(x).parent).color == Red) {
372
974k
        uint p = F(x).parent;
373
974k
        uint pp = F(p).parent;
374
974k
        Q_ASSERT(pp);
375
974k
        if (p == F(pp).left) {
376
160k
            uint y = F(pp).right;
377
160k
            if (y && F(y).color == Red) {
378
0
                F(p).color = Black;
379
0
                F(y).color = Black;
380
0
                F(pp).color = Red;
381
0
                x = pp;
382
160k
            } else {
383
160k
                if (x == F(p).right) {
384
160k
                    x = p;
385
160k
                    rotateLeft(x);
386
160k
                    p = F(x).parent;
387
160k
                    pp = F(p).parent;
388
160k
                }
389
160k
                F(p).color = Black;
390
160k
                if (pp) {
391
160k
                    F(pp).color = Red;
392
160k
                    rotateRight(pp);
393
160k
                }
394
160k
            }
395
813k
        } else {
396
813k
            uint y = F(pp).left;
397
813k
            if (y && F(y).color == Red) {
398
479k
                F(p).color = Black;
399
479k
                F(y).color = Black;
400
479k
                F(pp).color = Red;
401
479k
                x = pp;
402
479k
            } else {
403
334k
                if (x == F(p).left) {
404
0
                    x = p;
405
0
                    rotateRight(x);
406
0
                    p = F(x).parent;
407
0
                    pp = F(p).parent;
408
0
                }
409
334k
                F(p).color = Black;
410
334k
                if (pp) {
411
334k
                    F(pp).color = Red;
412
334k
                    rotateLeft(pp);
413
334k
                }
414
334k
            }
415
813k
        }
416
974k
    }
417
621k
    F(root()).color = Black;
418
621k
}
QFragmentMapData<QTextFragmentData>::rebalance(unsigned int)
Line
Count
Source
368
364k
{
369
364k
    F(x).color = Red;
370
371
935k
    while (F(x).parent && F(F(x).parent).color == Red) {
372
570k
        uint p = F(x).parent;
373
570k
        uint pp = F(p).parent;
374
570k
        Q_ASSERT(pp);
375
570k
        if (p == F(pp).left) {
376
160k
            uint y = F(pp).right;
377
160k
            if (y && F(y).color == Red) {
378
0
                F(p).color = Black;
379
0
                F(y).color = Black;
380
0
                F(pp).color = Red;
381
0
                x = pp;
382
160k
            } else {
383
160k
                if (x == F(p).right) {
384
160k
                    x = p;
385
160k
                    rotateLeft(x);
386
160k
                    p = F(x).parent;
387
160k
                    pp = F(p).parent;
388
160k
                }
389
160k
                F(p).color = Black;
390
160k
                if (pp) {
391
160k
                    F(pp).color = Red;
392
160k
                    rotateRight(pp);
393
160k
                }
394
160k
            }
395
409k
        } else {
396
409k
            uint y = F(pp).left;
397
409k
            if (y && F(y).color == Red) {
398
281k
                F(p).color = Black;
399
281k
                F(y).color = Black;
400
281k
                F(pp).color = Red;
401
281k
                x = pp;
402
281k
            } else {
403
128k
                if (x == F(p).left) {
404
0
                    x = p;
405
0
                    rotateRight(x);
406
0
                    p = F(x).parent;
407
0
                    pp = F(p).parent;
408
0
                }
409
128k
                F(p).color = Black;
410
128k
                if (pp) {
411
128k
                    F(pp).color = Red;
412
128k
                    rotateLeft(pp);
413
128k
                }
414
128k
            }
415
409k
        }
416
570k
    }
417
364k
    F(root()).color = Black;
418
364k
}
QFragmentMapData<QTextBlockData>::rebalance(unsigned int)
Line
Count
Source
368
257k
{
369
257k
    F(x).color = Red;
370
371
661k
    while (F(x).parent && F(F(x).parent).color == Red) {
372
404k
        uint p = F(x).parent;
373
404k
        uint pp = F(p).parent;
374
404k
        Q_ASSERT(pp);
375
404k
        if (p == F(pp).left) {
376
0
            uint y = F(pp).right;
377
0
            if (y && F(y).color == Red) {
378
0
                F(p).color = Black;
379
0
                F(y).color = Black;
380
0
                F(pp).color = Red;
381
0
                x = pp;
382
0
            } else {
383
0
                if (x == F(p).right) {
384
0
                    x = p;
385
0
                    rotateLeft(x);
386
0
                    p = F(x).parent;
387
0
                    pp = F(p).parent;
388
0
                }
389
0
                F(p).color = Black;
390
0
                if (pp) {
391
0
                    F(pp).color = Red;
392
0
                    rotateRight(pp);
393
0
                }
394
0
            }
395
404k
        } else {
396
404k
            uint y = F(pp).left;
397
404k
            if (y && F(y).color == Red) {
398
198k
                F(p).color = Black;
399
198k
                F(y).color = Black;
400
198k
                F(pp).color = Red;
401
198k
                x = pp;
402
205k
            } else {
403
205k
                if (x == F(p).left) {
404
0
                    x = p;
405
0
                    rotateRight(x);
406
0
                    p = F(x).parent;
407
0
                    pp = F(p).parent;
408
0
                }
409
205k
                F(p).color = Black;
410
205k
                if (pp) {
411
205k
                    F(pp).color = Red;
412
205k
                    rotateLeft(pp);
413
205k
                }
414
205k
            }
415
404k
        }
416
404k
    }
417
257k
    F(root()).color = Black;
418
257k
}
419
420
421
template <class Fragment>
422
uint QFragmentMapData<Fragment>::erase_single(uint z)
423
0
{
424
0
    uint w = previous(z);
425
0
    uint y = z;
426
0
    uint x;
427
0
    uint p;
428
429
0
    if (!F(y).left) {
430
0
        x = F(y).right;
431
0
    } else if (!F(y).right) {
432
0
        x = F(y).left;
433
0
    } else {
434
0
        y = F(y).right;
435
0
        while (F(y).left)
436
0
            y = F(y).left;
437
0
        x = F(y).right;
438
0
    }
439
440
0
    if (y != z) {
441
0
        F(F(z).left).parent = y;
442
0
        F(y).left = F(z).left;
443
0
        for (uint field = 0; field < Fragment::size_array_max; ++field)
444
0
            F(y).size_left_array[field] = F(z).size_left_array[field];
445
0
        if (y != F(z).right) {
446
            /*
447
                     z                y
448
                    / \              / \
449
                   a   b            a   b
450
                      /                /
451
                    ...     -->      ...
452
                    /                /
453
                   y                x
454
                  / \
455
                 0   x
456
             */
457
0
            p = F(y).parent;
458
0
            if (x)
459
0
                F(x).parent = p;
460
0
            F(p).left = x;
461
0
            F(y).right = F(z).right;
462
0
            F(F(z).right).parent = y;
463
0
            uint n = p;
464
0
            while (n != y) {
465
0
                for (uint field = 0; field < Fragment::size_array_max; ++field)
466
0
                    F(n).size_left_array[field] -= F(y).size_array[field];
467
0
                n = F(n).parent;
468
0
            }
469
0
        } else {
470
            /*
471
                     z                y
472
                    / \              / \
473
                   a   y     -->    a   x
474
                      / \
475
                     0   x
476
             */
477
0
            p = y;
478
0
        }
479
0
        uint zp = F(z).parent;
480
0
        if (!zp) {
481
0
            Q_ASSERT(head->root == z);
482
0
            head->root = y;
483
0
        } else if (F(zp).left == z) {
484
0
            F(zp).left = y;
485
0
            for (uint field = 0; field < Fragment::size_array_max; ++field)
486
0
                F(zp).size_left_array[field] -= F(z).size_array[field];
487
0
        } else {
488
0
            F(zp).right = y;
489
0
        }
490
0
        F(y).parent = zp;
491
        // Swap the colors
492
0
        uint c = F(y).color;
493
0
        F(y).color = F(z).color;
494
0
        F(z).color = c;
495
0
        y = z;
496
0
    } else {
497
        /*
498
                p          p            p          p
499
               /          /              \          \
500
              z    -->   x                z  -->     x
501
              |                           |
502
              x                           x
503
         */
504
0
        p = F(z).parent;
505
0
        if (x)
506
0
            F(x).parent = p;
507
0
        if (!p) {
508
0
            Q_ASSERT(head->root == z);
509
0
            head->root = x;
510
0
        } else if (F(p).left == z) {
511
0
            F(p).left = x;
512
0
            for (uint field = 0; field < Fragment::size_array_max; ++field)
513
0
                F(p).size_left_array[field] -= F(z).size_array[field];
514
0
        } else {
515
0
            F(p).right = x;
516
0
        }
517
0
    }
518
0
    uint n = z;
519
0
    while (F(n).parent) {
520
0
        uint p = F(n).parent;
521
0
        if (F(p).left == n) {
522
0
            for (uint field = 0; field < Fragment::size_array_max; ++field)
523
0
                F(p).size_left_array[field] -= F(z).size_array[field];
524
0
        }
525
0
        n = p;
526
0
    }
527
528
0
    freeFragment(z);
529
530
531
0
    if (F(y).color != Red) {
532
0
        while (F(x).parent && (x == 0 || F(x).color == Black)) {
533
0
            if (x == F(p).left) {
534
0
                uint w = F(p).right;
535
0
                if (F(w).color == Red) {
536
0
                    F(w).color = Black;
537
0
                    F(p).color = Red;
538
0
                    rotateLeft(p);
539
0
                    w = F(p).right;
540
0
                }
541
0
                if ((F(w).left == 0 || F(F(w).left).color == Black) &&
542
0
                    (F(w).right == 0 || F(F(w).right).color == Black)) {
543
0
                    F(w).color = Red;
544
0
                    x = p;
545
0
                    p = F(x).parent;
546
0
                } else {
547
0
                    if (F(w).right == 0 || F(F(w).right).color == Black) {
548
0
                        if (F(w).left)
549
0
                            F(F(w).left).color = Black;
550
0
                        F(w).color = Red;
551
0
                        rotateRight(F(p).right);
552
0
                        w = F(p).right;
553
0
                    }
554
0
                    F(w).color = F(p).color;
555
0
                    F(p).color = Black;
556
0
                    if (F(w).right)
557
0
                        F(F(w).right).color = Black;
558
0
                    rotateLeft(p);
559
0
                    break;
560
0
                }
561
0
            } else {
562
0
                uint w = F(p).left;
563
0
                if (F(w).color == Red) {
564
0
                    F(w).color = Black;
565
0
                    F(p).color = Red;
566
0
                    rotateRight(p);
567
0
                    w = F(p).left;
568
0
                }
569
0
                if ((F(w).right == 0 || F(F(w).right).color == Black) &&
570
0
                    (F(w).left == 0 || F(F(w).left).color == Black)) {
571
0
                    F(w).color = Red;
572
0
                    x = p;
573
0
                    p = F(x).parent;
574
0
                } else {
575
0
                    if (F(w).left == 0 || F(F(w).left).color == Black) {
576
0
                        if (F(w).right)
577
0
                            F(F(w).right).color = Black;
578
0
                        F(w).color = Red;
579
0
                        rotateLeft(F(p).left);
580
0
                        w = F(p).left;
581
0
                    }
582
0
                    F(w).color = F(p).color;
583
0
                    F(p).color = Black;
584
0
                    if (F(w).left)
585
0
                        F(F(w).left).color = Black;
586
0
                    rotateRight(p);
587
0
                    break;
588
0
                }
589
0
            }
590
0
        }
591
0
        if (x)
592
0
            F(x).color = Black;
593
0
    }
594
595
0
    return w;
596
0
}
Unexecuted instantiation: QFragmentMapData<QTextFragmentData>::erase_single(unsigned int)
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::erase_single(unsigned int)
597
598
template <class Fragment>
599
uint QFragmentMapData<Fragment>::findNode(int k, uint field) const
600
6.17M
{
601
6.17M
    Q_ASSERT(field < Fragment::size_array_max);
602
6.17M
    uint x = root();
603
604
6.17M
    uint s = k;
605
38.5M
    while (x) {
606
37.7M
        if (sizeLeft(x, field) <= s) {
607
31.4M
            if (s < sizeLeft(x, field) + size(x, field))
608
5.43M
                return x;
609
26.0M
            s -= sizeLeft(x, field) + size(x, field);
610
26.0M
            x = F(x).right;
611
26.0M
        } else {
612
6.31M
            x = F(x).left;
613
6.31M
        }
614
37.7M
    }
615
744k
    return 0;
616
6.17M
}
QFragmentMapData<QTextFragmentData>::findNode(int, unsigned int) const
Line
Count
Source
600
4.33M
{
601
4.33M
    Q_ASSERT(field < Fragment::size_array_max);
602
4.33M
    uint x = root();
603
604
4.33M
    uint s = k;
605
26.0M
    while (x) {
606
25.9M
        if (sizeLeft(x, field) <= s) {
607
20.0M
            if (s < sizeLeft(x, field) + size(x, field))
608
4.28M
                return x;
609
15.7M
            s -= sizeLeft(x, field) + size(x, field);
610
15.7M
            x = F(x).right;
611
15.7M
        } else {
612
5.97M
            x = F(x).left;
613
5.97M
        }
614
25.9M
    }
615
44.9k
    return 0;
616
4.33M
}
QFragmentMapData<QTextBlockData>::findNode(int, unsigned int) const
Line
Count
Source
600
1.84M
{
601
1.84M
    Q_ASSERT(field < Fragment::size_array_max);
602
1.84M
    uint x = root();
603
604
1.84M
    uint s = k;
605
12.4M
    while (x) {
606
11.7M
        if (sizeLeft(x, field) <= s) {
607
11.4M
            if (s < sizeLeft(x, field) + size(x, field))
608
1.14M
                return x;
609
10.2M
            s -= sizeLeft(x, field) + size(x, field);
610
10.2M
            x = F(x).right;
611
10.2M
        } else {
612
348k
            x = F(x).left;
613
348k
        }
614
11.7M
    }
615
699k
    return 0;
616
1.84M
}
617
618
template <class Fragment>
619
uint QFragmentMapData<Fragment>::insert_single(int key, uint length)
620
621k
{
621
621k
    Q_ASSERT(!findNode(key) || (int)this->position(findNode(key)) == key);
622
623
621k
    uint z = createFragment();
624
625
621k
    F(z).left = 0;
626
621k
    F(z).right = 0;
627
621k
    F(z).size_array[0] = length;
628
1.13M
    for (uint field = 1; field < Fragment::size_array_max; ++field)
629
514k
        F(z).size_array[field] = 1;
630
1.75M
    for (uint field = 0; field < Fragment::size_array_max; ++field)
631
1.13M
        F(z).size_left_array[field] = 0;
632
633
621k
    uint y = 0;
634
621k
    uint x = root();
635
636
621k
    Q_ASSERT(!x || F(x).parent == 0);
637
638
621k
    uint s = key;
639
621k
    bool right = false;
640
6.11M
    while (x) {
641
5.49M
        y = x;
642
5.49M
        if (s <= F(x).size_left_array[0]) {
643
342k
            x = F(x).left;
644
342k
            right = false;
645
5.14M
        } else {
646
5.14M
            s -= F(x).size_left_array[0] + F(x).size_array[0];
647
5.14M
            x = F(x).right;
648
5.14M
            right = true;
649
5.14M
        }
650
5.49M
    }
651
652
621k
    F(z).parent = y;
653
621k
    if (!y) {
654
44.9k
        head->root = z;
655
576k
    } else if (!right) {
656
181k
        F(y).left = z;
657
362k
        for (uint field = 0; field < Fragment::size_array_max; ++field)
658
181k
            F(y).size_left_array[field] = F(z).size_array[field];
659
395k
    } else {
660
395k
        F(y).right = z;
661
395k
    }
662
5.53M
    while (y && F(y).parent) {
663
4.91M
        uint p = F(y).parent;
664
4.91M
        if (F(p).left == y) {
665
321k
            for (uint field = 0; field < Fragment::size_array_max; ++field)
666
160k
                F(p).size_left_array[field] += F(z).size_array[field];
667
160k
        }
668
4.91M
        y = p;
669
4.91M
    }
670
621k
    rebalance(z);
671
672
621k
    return z;
673
621k
}
QFragmentMapData<QTextFragmentData>::insert_single(int, unsigned int)
Line
Count
Source
620
364k
{
621
364k
    Q_ASSERT(!findNode(key) || (int)this->position(findNode(key)) == key);
622
623
364k
    uint z = createFragment();
624
625
364k
    F(z).left = 0;
626
364k
    F(z).right = 0;
627
364k
    F(z).size_array[0] = length;
628
364k
    for (uint field = 1; field < Fragment::size_array_max; ++field)
629
0
        F(z).size_array[field] = 1;
630
729k
    for (uint field = 0; field < Fragment::size_array_max; ++field)
631
364k
        F(z).size_left_array[field] = 0;
632
633
364k
    uint y = 0;
634
364k
    uint x = root();
635
636
364k
    Q_ASSERT(!x || F(x).parent == 0);
637
638
364k
    uint s = key;
639
364k
    bool right = false;
640
3.57M
    while (x) {
641
3.21M
        y = x;
642
3.21M
        if (s <= F(x).size_left_array[0]) {
643
342k
            x = F(x).left;
644
342k
            right = false;
645
2.87M
        } else {
646
2.87M
            s -= F(x).size_left_array[0] + F(x).size_array[0];
647
2.87M
            x = F(x).right;
648
2.87M
            right = true;
649
2.87M
        }
650
3.21M
    }
651
652
364k
    F(z).parent = y;
653
364k
    if (!y) {
654
22.4k
        head->root = z;
655
342k
    } else if (!right) {
656
181k
        F(y).left = z;
657
362k
        for (uint field = 0; field < Fragment::size_array_max; ++field)
658
181k
            F(y).size_left_array[field] = F(z).size_array[field];
659
181k
    } else {
660
160k
        F(y).right = z;
661
160k
    }
662
3.23M
    while (y && F(y).parent) {
663
2.87M
        uint p = F(y).parent;
664
2.87M
        if (F(p).left == y) {
665
321k
            for (uint field = 0; field < Fragment::size_array_max; ++field)
666
160k
                F(p).size_left_array[field] += F(z).size_array[field];
667
160k
        }
668
2.87M
        y = p;
669
2.87M
    }
670
364k
    rebalance(z);
671
672
364k
    return z;
673
364k
}
QFragmentMapData<QTextBlockData>::insert_single(int, unsigned int)
Line
Count
Source
620
257k
{
621
257k
    Q_ASSERT(!findNode(key) || (int)this->position(findNode(key)) == key);
622
623
257k
    uint z = createFragment();
624
625
257k
    F(z).left = 0;
626
257k
    F(z).right = 0;
627
257k
    F(z).size_array[0] = length;
628
772k
    for (uint field = 1; field < Fragment::size_array_max; ++field)
629
514k
        F(z).size_array[field] = 1;
630
1.02M
    for (uint field = 0; field < Fragment::size_array_max; ++field)
631
772k
        F(z).size_left_array[field] = 0;
632
633
257k
    uint y = 0;
634
257k
    uint x = root();
635
636
257k
    Q_ASSERT(!x || F(x).parent == 0);
637
638
257k
    uint s = key;
639
257k
    bool right = false;
640
2.53M
    while (x) {
641
2.27M
        y = x;
642
2.27M
        if (s <= F(x).size_left_array[0]) {
643
0
            x = F(x).left;
644
0
            right = false;
645
2.27M
        } else {
646
2.27M
            s -= F(x).size_left_array[0] + F(x).size_array[0];
647
2.27M
            x = F(x).right;
648
2.27M
            right = true;
649
2.27M
        }
650
2.27M
    }
651
652
257k
    F(z).parent = y;
653
257k
    if (!y) {
654
22.4k
        head->root = z;
655
234k
    } else if (!right) {
656
0
        F(y).left = z;
657
0
        for (uint field = 0; field < Fragment::size_array_max; ++field)
658
0
            F(y).size_left_array[field] = F(z).size_array[field];
659
234k
    } else {
660
234k
        F(y).right = z;
661
234k
    }
662
2.29M
    while (y && F(y).parent) {
663
2.04M
        uint p = F(y).parent;
664
2.04M
        if (F(p).left == y) {
665
0
            for (uint field = 0; field < Fragment::size_array_max; ++field)
666
0
                F(p).size_left_array[field] += F(z).size_array[field];
667
0
        }
668
2.04M
        y = p;
669
2.04M
    }
670
257k
    rebalance(z);
671
672
257k
    return z;
673
257k
}
674
675
676
template <class Fragment>
677
3.30M
int QFragmentMapData<Fragment>::length(uint field) const {
678
3.30M
    uint root = this->root();
679
3.30M
    return root ? sizeLeft(root, field) + size(root, field) + sizeRight(root, field) : 0;
680
3.30M
}
QFragmentMapData<QTextFragmentData>::length(unsigned int) const
Line
Count
Source
677
1.65M
int QFragmentMapData<Fragment>::length(uint field) const {
678
1.65M
    uint root = this->root();
679
1.65M
    return root ? sizeLeft(root, field) + size(root, field) + sizeRight(root, field) : 0;
680
1.65M
}
QFragmentMapData<QTextBlockData>::length(unsigned int) const
Line
Count
Source
677
1.65M
int QFragmentMapData<Fragment>::length(uint field) const {
678
1.65M
    uint root = this->root();
679
1.65M
    return root ? sizeLeft(root, field) + size(root, field) + sizeRight(root, field) : 0;
680
1.65M
}
681
682
683
template <class Fragment> // NOTE: must inherit QFragment
684
class QFragmentMap
685
{
686
public:
687
    class Iterator
688
    {
689
    public:
690
        QFragmentMap *pt;
691
        quint32 n;
692
693
        Iterator() : pt(0), n(0) {}
694
44.9k
        Iterator(QFragmentMap *p, int node) : pt(p), n(node) {}
QFragmentMap<QTextBlockData>::Iterator::Iterator(QFragmentMap<QTextBlockData>*, int)
Line
Count
Source
694
22.4k
        Iterator(QFragmentMap *p, int node) : pt(p), n(node) {}
QFragmentMap<QTextFragmentData>::Iterator::Iterator(QFragmentMap<QTextFragmentData>*, int)
Line
Count
Source
694
22.4k
        Iterator(QFragmentMap *p, int node) : pt(p), n(node) {}
695
        Iterator(const Iterator& it) : pt(it.pt), n(it.n) {}
696
697
1.28M
        inline bool atEnd() const { return !n; }
QFragmentMap<QTextBlockData>::Iterator::atEnd() const
Line
Count
Source
697
537k
        inline bool atEnd() const { return !n; }
QFragmentMap<QTextFragmentData>::Iterator::atEnd() const
Line
Count
Source
697
751k
        inline bool atEnd() const { return !n; }
698
699
        bool operator==(const Iterator& it) const { return pt == it.pt && n == it.n; }
700
        bool operator!=(const Iterator& it) const { return pt != it.pt || n != it.n; }
701
        bool operator<(const Iterator &it) const { return position() < it.position(); }
702
703
        Fragment *operator*() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
704
        const Fragment *operator*() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
705
0
        Fragment *operator->() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::Iterator::operator->()
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::Iterator::operator->()
706
        const Fragment *operator->() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
707
708
0
        int position() const { Q_ASSERT(!atEnd()); return pt->data.position(n); }
709
        const Fragment *value() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
710
621k
        Fragment *value() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
QFragmentMap<QTextBlockData>::Iterator::value()
Line
Count
Source
710
257k
        Fragment *value() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
QFragmentMap<QTextFragmentData>::Iterator::value()
Line
Count
Source
710
364k
        Fragment *value() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
711
712
621k
        Iterator& operator++() {
713
621k
            n = pt->data.next(n);
714
621k
            return *this;
715
621k
        }
QFragmentMap<QTextBlockData>::Iterator::operator++()
Line
Count
Source
712
257k
        Iterator& operator++() {
713
257k
            n = pt->data.next(n);
714
257k
            return *this;
715
257k
        }
QFragmentMap<QTextFragmentData>::Iterator::operator++()
Line
Count
Source
712
364k
        Iterator& operator++() {
713
364k
            n = pt->data.next(n);
714
364k
            return *this;
715
364k
        }
716
        Iterator& operator--() {
717
            n = pt->data.previous(n);
718
            return *this;
719
        }
720
721
    };
722
723
724
    class ConstIterator
725
    {
726
    public:
727
        const QFragmentMap *pt;
728
        quint32 n;
729
730
        /**
731
         * Functions
732
         */
733
        ConstIterator() : pt(0), n(0) {}
734
3.25M
        ConstIterator(const QFragmentMap *p, int node) : pt(p), n(node) {}
QFragmentMap<QTextFragmentData>::ConstIterator::ConstIterator(QFragmentMap<QTextFragmentData> const*, int)
Line
Count
Source
734
3.25M
        ConstIterator(const QFragmentMap *p, int node) : pt(p), n(node) {}
Unexecuted instantiation: QFragmentMap<QTextBlockData>::ConstIterator::ConstIterator(QFragmentMap<QTextBlockData> const*, int)
735
        ConstIterator(const ConstIterator& it) : pt(it.pt), n(it.n) {}
736
        ConstIterator(const Iterator& it) : pt(it.pt), n(it.n) {}
737
738
2.10M
        inline bool atEnd() const { return !n; }
739
740
537k
        bool operator==(const ConstIterator& it) const { return pt == it.pt && n == it.n; }
741
1.25M
        bool operator!=(const ConstIterator& it) const { return pt != it.pt || n != it.n; }
742
        bool operator<(const ConstIterator &it) const { return position() < it.position(); }
743
744
0
        const Fragment *operator*()  const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
745
147k
        const Fragment *operator->()  const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
746
747
0
        int position() const { Q_ASSERT(!atEnd()); return pt->data.position(n); }
748
0
        int size() const { Q_ASSERT(!atEnd()); return pt->data.size(n); }
749
1.96M
        const Fragment *value() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
750
751
572k
        ConstIterator& operator++() {
752
572k
            n = pt->data.next(n);
753
572k
            return *this;
754
572k
        }
755
        ConstIterator& operator--() {
756
            n = pt->data.previous(n);
757
            return *this;
758
        }
759
    };
760
761
762
44.9k
    QFragmentMap() {}
QFragmentMap<QTextFragmentData>::QFragmentMap()
Line
Count
Source
762
22.4k
    QFragmentMap() {}
QFragmentMap<QTextBlockData>::QFragmentMap()
Line
Count
Source
762
22.4k
    QFragmentMap() {}
763
    ~QFragmentMap()
764
44.9k
    {
765
44.9k
        if (!data.fragments)
766
0
            return; // in case of out-of-memory, we won't have fragments
767
666k
        for (Iterator it = begin(); !it.atEnd(); ++it)
768
621k
            it.value()->free();
769
44.9k
    }
QFragmentMap<QTextFragmentData>::~QFragmentMap()
Line
Count
Source
764
22.4k
    {
765
22.4k
        if (!data.fragments)
766
0
            return; // in case of out-of-memory, we won't have fragments
767
387k
        for (Iterator it = begin(); !it.atEnd(); ++it)
768
364k
            it.value()->free();
769
22.4k
    }
QFragmentMap<QTextBlockData>::~QFragmentMap()
Line
Count
Source
764
22.4k
    {
765
22.4k
        if (!data.fragments)
766
0
            return; // in case of out-of-memory, we won't have fragments
767
279k
        for (Iterator it = begin(); !it.atEnd(); ++it)
768
257k
            it.value()->free();
769
22.4k
    }
770
771
0
    inline void clear() {
772
0
        for (Iterator it = begin(); !it.atEnd(); ++it)
773
0
            it.value()->free();
774
0
        data.init();
775
0
    }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::clear()
Unexecuted instantiation: QFragmentMap<QTextBlockData>::clear()
776
777
44.9k
    inline Iterator begin() { return Iterator(this, data.minimum(data.root())); }
QFragmentMap<QTextBlockData>::begin()
Line
Count
Source
777
22.4k
    inline Iterator begin() { return Iterator(this, data.minimum(data.root())); }
QFragmentMap<QTextFragmentData>::begin()
Line
Count
Source
777
22.4k
    inline Iterator begin() { return Iterator(this, data.minimum(data.root())); }
778
    inline Iterator end() { return Iterator(this, 0); }
779
0
    inline ConstIterator begin() const { return ConstIterator(this, data.minimum(data.root())); }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::begin() const
Unexecuted instantiation: QFragmentMap<QTextBlockData>::begin() const
780
0
    inline ConstIterator end() const { return ConstIterator(this, 0); }
781
782
0
    inline ConstIterator last() const { return ConstIterator(this, data.maximum(data.root())); }
783
784
    inline bool isEmpty() const { return data.head->node_count == 0; }
785
120k
    inline int numNodes() const { return data.head->node_count; }
786
3.30M
    int length(uint field = 0) const { return data.length(field); }
QFragmentMap<QTextFragmentData>::length(unsigned int) const
Line
Count
Source
786
1.65M
    int length(uint field = 0) const { return data.length(field); }
QFragmentMap<QTextBlockData>::length(unsigned int) const
Line
Count
Source
786
1.65M
    int length(uint field = 0) const { return data.length(field); }
787
788
0
    Iterator find(int k, uint field = 0) { return Iterator(this, data.findNode(k, field)); }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::find(int, unsigned int)
Unexecuted instantiation: QFragmentMap<QTextBlockData>::find(int, unsigned int)
789
3.25M
    ConstIterator find(int k, uint field = 0) const { return ConstIterator(this, data.findNode(k, field)); }
790
791
1.95M
    uint findNode(int k, uint field = 0) const { return data.findNode(k, field); }
QFragmentMap<QTextBlockData>::findNode(int, unsigned int) const
Line
Count
Source
791
1.58M
    uint findNode(int k, uint field = 0) const { return data.findNode(k, field); }
QFragmentMap<QTextFragmentData>::findNode(int, unsigned int) const
Line
Count
Source
791
364k
    uint findNode(int k, uint field = 0) const { return data.findNode(k, field); }
792
793
    uint insert_single(int key, uint length)
794
621k
    {
795
621k
        uint f = data.insert_single(key, length);
796
621k
        if (f != 0) {
797
621k
            Fragment *frag = fragment(f);
798
621k
            Q_ASSERT(frag);
799
621k
            frag->initialize();
800
621k
        }
801
621k
        return f;
802
621k
    }
QFragmentMap<QTextFragmentData>::insert_single(int, unsigned int)
Line
Count
Source
794
364k
    {
795
364k
        uint f = data.insert_single(key, length);
796
364k
        if (f != 0) {
797
364k
            Fragment *frag = fragment(f);
798
            Q_ASSERT(frag);
799
364k
            frag->initialize();
800
364k
        }
801
364k
        return f;
802
364k
    }
QFragmentMap<QTextBlockData>::insert_single(int, unsigned int)
Line
Count
Source
794
257k
    {
795
257k
        uint f = data.insert_single(key, length);
796
257k
        if (f != 0) {
797
257k
            Fragment *frag = fragment(f);
798
            Q_ASSERT(frag);
799
257k
            frag->initialize();
800
257k
        }
801
257k
        return f;
802
257k
    }
803
    uint erase_single(uint f)
804
0
    {
805
0
      if (f != 0) {
806
0
          Fragment *frag = fragment(f);
807
0
          Q_ASSERT(frag);
808
0
          frag->free();
809
0
      }
810
0
      return data.erase_single(f);
811
0
    }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::erase_single(unsigned int)
Unexecuted instantiation: QFragmentMap<QTextBlockData>::erase_single(unsigned int)
812
813
8.12M
    inline Fragment *fragment(uint index) {
814
8.12M
        Q_ASSERT(index != 0);
815
8.12M
        return data.fragment(index);
816
8.12M
    }
QFragmentMap<QTextBlockData>::fragment(unsigned int)
Line
Count
Source
813
6.86M
    inline Fragment *fragment(uint index) {
814
        Q_ASSERT(index != 0);
815
6.86M
        return data.fragment(index);
816
6.86M
    }
QFragmentMap<QTextFragmentData>::fragment(unsigned int)
Line
Count
Source
813
1.26M
    inline Fragment *fragment(uint index) {
814
        Q_ASSERT(index != 0);
815
1.26M
        return data.fragment(index);
816
1.26M
    }
817
2.10M
    inline const Fragment *fragment(uint index) const {
818
2.10M
        Q_ASSERT(index != 0);
819
2.10M
        return data.fragment(index);
820
2.10M
    }
QFragmentMap<QTextFragmentData>::fragment(unsigned int) const
Line
Count
Source
817
2.10M
    inline const Fragment *fragment(uint index) const {
818
        Q_ASSERT(index != 0);
819
2.10M
        return data.fragment(index);
820
2.10M
    }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::fragment(unsigned int) const
821
5.62M
    inline uint position(uint node, uint field = 0) const { return data.position(node, field); }
QFragmentMap<QTextBlockData>::position(unsigned int, unsigned int) const
Line
Count
Source
821
5.28M
    inline uint position(uint node, uint field = 0) const { return data.position(node, field); }
QFragmentMap<QTextFragmentData>::position(unsigned int, unsigned int) const
Line
Count
Source
821
342k
    inline uint position(uint node, uint field = 0) const { return data.position(node, field); }
822
3.46M
    inline bool isValid(uint n) const { return data.isValid(n); }
823
1.99M
    inline uint next(uint n) const { return data.next(n); }
QFragmentMap<QTextBlockData>::next(unsigned int) const
Line
Count
Source
823
1.91M
    inline uint next(uint n) const { return data.next(n); }
QFragmentMap<QTextFragmentData>::next(unsigned int) const
Line
Count
Source
823
84.8k
    inline uint next(uint n) const { return data.next(n); }
824
576k
    inline uint previous(uint n) const { return data.previous(n); }
QFragmentMap<QTextFragmentData>::previous(unsigned int) const
Line
Count
Source
824
107k
    inline uint previous(uint n) const { return data.previous(n); }
QFragmentMap<QTextBlockData>::previous(unsigned int) const
Line
Count
Source
824
469k
    inline uint previous(uint n) const { return data.previous(n); }
825
3.55M
    inline uint size(uint node, uint field = 0) const { return data.size(node, field); }
QFragmentMap<QTextBlockData>::size(unsigned int, unsigned int) const
Line
Count
Source
825
3.55M
    inline uint size(uint node, uint field = 0) const { return data.size(node, field); }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::size(unsigned int, unsigned int) const
826
    inline void setSize(uint node, int new_size, uint field = 0)
827
107k
        { data.setSize(node, new_size, field);
828
107k
      if (node != 0 && field == 0) {
829
107k
          Fragment *frag = fragment(node);
830
107k
          Q_ASSERT(frag);
831
107k
          frag->invalidate();
832
107k
      }
833
107k
    }
QFragmentMap<QTextBlockData>::setSize(unsigned int, int, unsigned int)
Line
Count
Source
827
107k
        { data.setSize(node, new_size, field);
828
107k
      if (node != 0 && field == 0) {
829
107k
          Fragment *frag = fragment(node);
830
          Q_ASSERT(frag);
831
107k
          frag->invalidate();
832
107k
      }
833
107k
    }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::setSize(unsigned int, int, unsigned int)
834
835
22.4k
    inline int firstNode() const { return data.minimum(data.root()); }
836
837
private:
838
    friend class Iterator;
839
    friend class ConstIterator;
840
841
    QFragmentMapData<Fragment> data;
842
843
    QFragmentMap(const QFragmentMap& m);
844
    QFragmentMap& operator= (const QFragmentMap& m);
845
};
846
847
QT_END_NAMESPACE
848
849
#endif // QFRAGMENTMAP_P_H