Coverage Report

Created: 2026-03-12 07:14

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
16.4M
    inline Fragment *fragment(uint index) {
66
16.4M
        return (fragments + index);
67
16.4M
    }
QFragmentMapData<QTextBlockData>::fragment(unsigned int)
Line
Count
Source
65
14.6M
    inline Fragment *fragment(uint index) {
66
14.6M
        return (fragments + index);
67
14.6M
    }
QFragmentMapData<QTextFragmentData>::fragment(unsigned int)
Line
Count
Source
65
1.80M
    inline Fragment *fragment(uint index) {
66
1.80M
        return (fragments + index);
67
1.80M
    }
68
488M
    inline const Fragment *fragment(uint index) const {
69
488M
        return (fragments + index);
70
488M
    }
QFragmentMapData<QTextFragmentData>::fragment(unsigned int) const
Line
Count
Source
68
277M
    inline const Fragment *fragment(uint index) const {
69
277M
        return (fragments + index);
70
277M
    }
QFragmentMapData<QTextBlockData>::fragment(unsigned int) const
Line
Count
Source
68
211M
    inline const Fragment *fragment(uint index) const {
69
211M
        return (fragments + index);
70
211M
    }
71
72
73
120M
    inline Fragment &F(uint index) { return fragments[index] ; }
QFragmentMapData<QTextFragmentData>::F(unsigned int)
Line
Count
Source
73
66.6M
    inline Fragment &F(uint index) { return fragments[index] ; }
QFragmentMapData<QTextBlockData>::F(unsigned int)
Line
Count
Source
73
53.8M
    inline Fragment &F(uint index) { return fragments[index] ; }
74
112M
    inline const Fragment &F(uint index) const { return fragments[index] ; }
QFragmentMapData<QTextFragmentData>::F(unsigned int) const
Line
Count
Source
74
60.3M
    inline const Fragment &F(uint index) const { return fragments[index] ; }
QFragmentMapData<QTextBlockData>::F(unsigned int) const
Line
Count
Source
74
52.2M
    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
11.6M
    inline uint position(uint node, uint field = 0) const {
81
11.6M
        Q_ASSERT(field < Fragment::size_array_max);
82
11.6M
        const Fragment *f = fragment(node);
83
11.6M
        uint offset = f->size_left_array[field];
84
74.8M
        while (f->parent) {
85
63.2M
            uint p = f->parent;
86
63.2M
            f = fragment(p);
87
63.2M
            if (f->right == node)
88
44.9M
                offset += f->size_left_array[field] + f->size_array[field];
89
63.2M
            node = p;
90
63.2M
        }
91
11.6M
        return offset;
92
11.6M
    }
QFragmentMapData<QTextFragmentData>::position(unsigned int, unsigned int) const
Line
Count
Source
80
1.04M
    inline uint position(uint node, uint field = 0) const {
81
1.04M
        Q_ASSERT(field < Fragment::size_array_max);
82
1.04M
        const Fragment *f = fragment(node);
83
1.04M
        uint offset = f->size_left_array[field];
84
10.9M
        while (f->parent) {
85
9.85M
            uint p = f->parent;
86
9.85M
            f = fragment(p);
87
9.85M
            if (f->right == node)
88
9.85M
                offset += f->size_left_array[field] + f->size_array[field];
89
9.85M
            node = p;
90
9.85M
        }
91
1.04M
        return offset;
92
1.04M
    }
QFragmentMapData<QTextBlockData>::position(unsigned int, unsigned int) const
Line
Count
Source
80
10.6M
    inline uint position(uint node, uint field = 0) const {
81
10.6M
        Q_ASSERT(field < Fragment::size_array_max);
82
10.6M
        const Fragment *f = fragment(node);
83
10.6M
        uint offset = f->size_left_array[field];
84
63.9M
        while (f->parent) {
85
53.3M
            uint p = f->parent;
86
53.3M
            f = fragment(p);
87
53.3M
            if (f->right == node)
88
35.0M
                offset += f->size_left_array[field] + f->size_array[field];
89
53.3M
            node = p;
90
53.3M
        }
91
10.6M
        return offset;
92
10.6M
    }
93
4.90M
    inline uint sizeRight(uint node, uint field = 0) const {
94
4.90M
        Q_ASSERT(field < Fragment::size_array_max);
95
4.90M
        uint sr = 0;
96
4.90M
        const Fragment *f = fragment(node);
97
4.90M
        node = f->right;
98
49.5M
        while (node) {
99
44.6M
            f = fragment(node);
100
44.6M
            sr += f->size_left_array[field] + f->size_array[field];
101
44.6M
            node = f->right;
102
44.6M
        }
103
4.90M
        return sr;
104
4.90M
    }
QFragmentMapData<QTextFragmentData>::sizeRight(unsigned int, unsigned int) const
Line
Count
Source
93
2.31M
    inline uint sizeRight(uint node, uint field = 0) const {
94
2.31M
        Q_ASSERT(field < Fragment::size_array_max);
95
2.31M
        uint sr = 0;
96
2.31M
        const Fragment *f = fragment(node);
97
2.31M
        node = f->right;
98
21.4M
        while (node) {
99
19.1M
            f = fragment(node);
100
19.1M
            sr += f->size_left_array[field] + f->size_array[field];
101
19.1M
            node = f->right;
102
19.1M
        }
103
2.31M
        return sr;
104
2.31M
    }
QFragmentMapData<QTextBlockData>::sizeRight(unsigned int, unsigned int) const
Line
Count
Source
93
2.59M
    inline uint sizeRight(uint node, uint field = 0) const {
94
2.59M
        Q_ASSERT(field < Fragment::size_array_max);
95
2.59M
        uint sr = 0;
96
2.59M
        const Fragment *f = fragment(node);
97
2.59M
        node = f->right;
98
28.0M
        while (node) {
99
25.4M
            f = fragment(node);
100
25.4M
            sr += f->size_left_array[field] + f->size_array[field];
101
25.4M
            node = f->right;
102
25.4M
        }
103
2.59M
        return sr;
104
2.59M
    }
105
207M
    inline uint sizeLeft(uint node, uint field = 0) const {
106
207M
        Q_ASSERT(field < Fragment::size_array_max);
107
207M
        return fragment(node)->size_left_array[field];
108
207M
    }
QFragmentMapData<QTextFragmentData>::sizeLeft(unsigned int, unsigned int) const
Line
Count
Source
105
144M
    inline uint sizeLeft(uint node, uint field = 0) const {
106
        Q_ASSERT(field < Fragment::size_array_max);
107
144M
        return fragment(node)->size_left_array[field];
108
144M
    }
QFragmentMapData<QTextBlockData>::sizeLeft(unsigned int, unsigned int) const
Line
Count
Source
105
63.5M
    inline uint sizeLeft(uint node, uint field = 0) const {
106
        Q_ASSERT(field < Fragment::size_array_max);
107
63.5M
        return fragment(node)->size_left_array[field];
108
63.5M
    }
109
110
111
132M
    inline uint size(uint node, uint field = 0) const {
112
132M
        Q_ASSERT(field < Fragment::size_array_max);
113
132M
        return fragment(node)->size_array[field];
114
132M
    }
QFragmentMapData<QTextFragmentData>::size(unsigned int, unsigned int) const
Line
Count
Source
111
82.9M
    inline uint size(uint node, uint field = 0) const {
112
        Q_ASSERT(field < Fragment::size_array_max);
113
82.9M
        return fragment(node)->size_array[field];
114
82.9M
    }
QFragmentMapData<QTextBlockData>::size(unsigned int, unsigned int) const
Line
Count
Source
111
49.3M
    inline uint size(uint node, uint field = 0) const {
112
        Q_ASSERT(field < Fragment::size_array_max);
113
49.3M
        return fragment(node)->size_array[field];
114
49.3M
    }
115
116
113k
    inline void setSize(uint node, int new_size, uint field = 0) {
117
113k
        Q_ASSERT(field < Fragment::size_array_max);
118
113k
        Fragment *f = fragment(node);
119
113k
        int diff = new_size - f->size_array[field];
120
113k
        f->size_array[field] = new_size;
121
872k
        while (f->parent) {
122
759k
            uint p = f->parent;
123
759k
            f = fragment(p);
124
759k
            if (f->left == node)
125
0
                f->size_left_array[field] += diff;
126
759k
            node = p;
127
759k
        }
128
113k
    }
QFragmentMapData<QTextBlockData>::setSize(unsigned int, int, unsigned int)
Line
Count
Source
116
113k
    inline void setSize(uint node, int new_size, uint field = 0) {
117
113k
        Q_ASSERT(field < Fragment::size_array_max);
118
113k
        Fragment *f = fragment(node);
119
113k
        int diff = new_size - f->size_array[field];
120
113k
        f->size_array[field] = new_size;
121
872k
        while (f->parent) {
122
759k
            uint p = f->parent;
123
759k
            f = fragment(p);
124
759k
            if (f->left == node)
125
0
                f->size_left_array[field] += diff;
126
759k
            node = p;
127
759k
        }
128
113k
    }
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
69.6k
    uint minimum(uint n) const {
137
128k
        while (n && fragment(n)->left)
138
58.7k
            n = fragment(n)->left;
139
69.6k
        return n;
140
69.6k
    }
QFragmentMapData<QTextFragmentData>::minimum(unsigned int) const
Line
Count
Source
136
17.4k
    uint minimum(uint n) const {
137
46.5k
        while (n && fragment(n)->left)
138
29.1k
            n = fragment(n)->left;
139
17.4k
        return n;
140
17.4k
    }
QFragmentMapData<QTextBlockData>::minimum(unsigned int) const
Line
Count
Source
136
52.2k
    uint minimum(uint n) const {
137
81.8k
        while (n && fragment(n)->left)
138
29.5k
            n = fragment(n)->left;
139
52.2k
        return n;
140
52.2k
    }
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
18.7M
    inline uint root() const {
152
18.7M
        Q_ASSERT(!head->root || !fragment(head->root)->parent);
153
18.7M
        return head->root;
154
18.7M
    }
QFragmentMapData<QTextFragmentData>::root() const
Line
Count
Source
151
12.6M
    inline uint root() const {
152
        Q_ASSERT(!head->root || !fragment(head->root)->parent);
153
12.6M
        return head->root;
154
12.6M
    }
QFragmentMapData<QTextBlockData>::root() const
Line
Count
Source
151
6.06M
    inline uint root() const {
152
        Q_ASSERT(!head->root || !fragment(head->root)->parent);
153
6.06M
        return head->root;
154
6.06M
    }
155
    inline void setRoot(uint new_root) {
156
        Q_ASSERT(!head->root || !fragment(new_root)->parent);
157
        head->root = new_root;
158
    }
159
160
8.32M
    inline bool isValid(uint n) const {
161
8.32M
        return n > 0 && n != head->freelist;
162
8.32M
    }
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
34.8k
    : fragments(nullptr)
184
34.8k
{
185
34.8k
    init();
186
34.8k
}
QFragmentMapData<QTextFragmentData>::QFragmentMapData()
Line
Count
Source
183
17.4k
    : fragments(nullptr)
184
17.4k
{
185
17.4k
    init();
186
17.4k
}
QFragmentMapData<QTextBlockData>::QFragmentMapData()
Line
Count
Source
183
17.4k
    : fragments(nullptr)
184
17.4k
{
185
17.4k
    init();
186
17.4k
}
187
188
template <class Fragment>
189
void QFragmentMapData<Fragment>::init()
190
34.8k
{
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
34.8k
    Fragment *newFragments = (Fragment *)realloc(fragments, 64*fragmentSize);
194
34.8k
    if (newFragments) {
195
34.8k
        fragments = newFragments;
196
34.8k
        head->allocated = 64;
197
34.8k
    }
198
34.8k
    Q_CHECK_PTR(fragments);
199
200
34.8k
    head->tag = (((quint32)'p') << 24) | (((quint32)'m') << 16) | (((quint32)'a') << 8) | 'p'; //TAG('p', 'm', 'a', 'p');
201
34.8k
    head->root = 0;
202
34.8k
    head->freelist = 1;
203
34.8k
    head->node_count = 0;
204
    // mark all items to the right as unused
205
34.8k
    F(head->freelist).right = 0;
206
34.8k
}
QFragmentMapData<QTextFragmentData>::init()
Line
Count
Source
190
17.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
17.4k
    Fragment *newFragments = (Fragment *)realloc(fragments, 64*fragmentSize);
194
17.4k
    if (newFragments) {
195
17.4k
        fragments = newFragments;
196
17.4k
        head->allocated = 64;
197
17.4k
    }
198
17.4k
    Q_CHECK_PTR(fragments);
199
200
17.4k
    head->tag = (((quint32)'p') << 24) | (((quint32)'m') << 16) | (((quint32)'a') << 8) | 'p'; //TAG('p', 'm', 'a', 'p');
201
17.4k
    head->root = 0;
202
17.4k
    head->freelist = 1;
203
17.4k
    head->node_count = 0;
204
    // mark all items to the right as unused
205
17.4k
    F(head->freelist).right = 0;
206
17.4k
}
QFragmentMapData<QTextBlockData>::init()
Line
Count
Source
190
17.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
17.4k
    Fragment *newFragments = (Fragment *)realloc(fragments, 64*fragmentSize);
194
17.4k
    if (newFragments) {
195
17.4k
        fragments = newFragments;
196
17.4k
        head->allocated = 64;
197
17.4k
    }
198
17.4k
    Q_CHECK_PTR(fragments);
199
200
17.4k
    head->tag = (((quint32)'p') << 24) | (((quint32)'m') << 16) | (((quint32)'a') << 8) | 'p'; //TAG('p', 'm', 'a', 'p');
201
17.4k
    head->root = 0;
202
17.4k
    head->freelist = 1;
203
17.4k
    head->node_count = 0;
204
    // mark all items to the right as unused
205
17.4k
    F(head->freelist).right = 0;
206
17.4k
}
207
208
template <class Fragment>
209
QFragmentMapData<Fragment>::~QFragmentMapData()
210
34.8k
{
211
34.8k
    free(fragments);
212
34.8k
}
QFragmentMapData<QTextFragmentData>::~QFragmentMapData()
Line
Count
Source
210
17.4k
{
211
17.4k
    free(fragments);
212
17.4k
}
QFragmentMapData<QTextBlockData>::~QFragmentMapData()
Line
Count
Source
210
17.4k
{
211
17.4k
    free(fragments);
212
17.4k
}
213
214
template <class Fragment>
215
uint QFragmentMapData<Fragment>::createFragment()
216
962k
{
217
962k
    Q_ASSERT(head->freelist <= head->allocated);
218
219
962k
    uint freePos = head->freelist;
220
962k
    if (freePos == head->allocated) {
221
        // need to create some free space
222
6.26k
        auto blockInfo = qCalculateGrowingBlockSize(freePos + 1, fragmentSize);
223
6.26k
        Fragment *newFragments = (Fragment *)realloc(fragments, blockInfo.size);
224
6.26k
        Q_CHECK_PTR(newFragments);
225
6.26k
        fragments = newFragments;
226
6.26k
        head->allocated = quint32(blockInfo.elementCount);
227
6.26k
        F(freePos).right = 0;
228
6.26k
    }
229
230
962k
    uint nextPos = F(freePos).right;
231
962k
    if (!nextPos) {
232
962k
        nextPos = freePos+1;
233
962k
        if (nextPos < head->allocated)
234
956k
            F(nextPos).right = 0;
235
962k
    }
236
237
962k
    head->freelist = nextPos;
238
239
962k
    ++head->node_count;
240
241
962k
    return freePos;
242
962k
}
QFragmentMapData<QTextFragmentData>::createFragment()
Line
Count
Source
216
538k
{
217
538k
    Q_ASSERT(head->freelist <= head->allocated);
218
219
538k
    uint freePos = head->freelist;
220
538k
    if (freePos == head->allocated) {
221
        // need to create some free space
222
3.33k
        auto blockInfo = qCalculateGrowingBlockSize(freePos + 1, fragmentSize);
223
3.33k
        Fragment *newFragments = (Fragment *)realloc(fragments, blockInfo.size);
224
3.33k
        Q_CHECK_PTR(newFragments);
225
3.33k
        fragments = newFragments;
226
3.33k
        head->allocated = quint32(blockInfo.elementCount);
227
3.33k
        F(freePos).right = 0;
228
3.33k
    }
229
230
538k
    uint nextPos = F(freePos).right;
231
538k
    if (!nextPos) {
232
538k
        nextPos = freePos+1;
233
538k
        if (nextPos < head->allocated)
234
534k
            F(nextPos).right = 0;
235
538k
    }
236
237
538k
    head->freelist = nextPos;
238
239
538k
    ++head->node_count;
240
241
538k
    return freePos;
242
538k
}
QFragmentMapData<QTextBlockData>::createFragment()
Line
Count
Source
216
424k
{
217
424k
    Q_ASSERT(head->freelist <= head->allocated);
218
219
424k
    uint freePos = head->freelist;
220
424k
    if (freePos == head->allocated) {
221
        // need to create some free space
222
2.92k
        auto blockInfo = qCalculateGrowingBlockSize(freePos + 1, fragmentSize);
223
2.92k
        Fragment *newFragments = (Fragment *)realloc(fragments, blockInfo.size);
224
2.92k
        Q_CHECK_PTR(newFragments);
225
2.92k
        fragments = newFragments;
226
2.92k
        head->allocated = quint32(blockInfo.elementCount);
227
2.92k
        F(freePos).right = 0;
228
2.92k
    }
229
230
424k
    uint nextPos = F(freePos).right;
231
424k
    if (!nextPos) {
232
424k
        nextPos = freePos+1;
233
424k
        if (nextPos < head->allocated)
234
421k
            F(nextPos).right = 0;
235
424k
    }
236
237
424k
    head->freelist = nextPos;
238
239
424k
    ++head->node_count;
240
241
424k
    return freePos;
242
424k
}
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
6.44M
uint QFragmentMapData<Fragment>::next(uint n) const {
256
6.44M
    Q_ASSERT(n);
257
6.44M
    if (F(n).right) {
258
3.15M
        n = F(n).right;
259
5.63M
        while (F(n).left)
260
2.48M
            n = F(n).left;
261
3.29M
    } else {
262
3.29M
        uint y = F(n).parent;
263
6.07M
        while (F(n).parent && n == F(y).right) {
264
2.78M
            n = y;
265
2.78M
            y = F(y).parent;
266
2.78M
        }
267
3.29M
        n = y;
268
3.29M
    }
269
6.44M
    return n;
270
6.44M
}
QFragmentMapData<QTextBlockData>::next(unsigned int) const
Line
Count
Source
255
5.03M
uint QFragmentMapData<Fragment>::next(uint n) const {
256
5.03M
    Q_ASSERT(n);
257
5.03M
    if (F(n).right) {
258
2.59M
        n = F(n).right;
259
4.57M
        while (F(n).left)
260
1.97M
            n = F(n).left;
261
2.59M
    } else {
262
2.43M
        uint y = F(n).parent;
263
4.69M
        while (F(n).parent && n == F(y).right) {
264
2.25M
            n = y;
265
2.25M
            y = F(y).parent;
266
2.25M
        }
267
2.43M
        n = y;
268
2.43M
    }
269
5.03M
    return n;
270
5.03M
}
QFragmentMapData<QTextFragmentData>::next(unsigned int) const
Line
Count
Source
255
1.40M
uint QFragmentMapData<Fragment>::next(uint n) const {
256
1.40M
    Q_ASSERT(n);
257
1.40M
    if (F(n).right) {
258
550k
        n = F(n).right;
259
1.06M
        while (F(n).left)
260
512k
            n = F(n).left;
261
858k
    } else {
262
858k
        uint y = F(n).parent;
263
1.38M
        while (F(n).parent && n == F(y).right) {
264
529k
            n = y;
265
529k
            y = F(y).parent;
266
529k
        }
267
858k
        n = y;
268
858k
    }
269
1.40M
    return n;
270
1.40M
}
271
272
template <class Fragment>
273
927k
uint QFragmentMapData<Fragment>::previous(uint n) const {
274
927k
    if (!n)
275
0
        return maximum(root());
276
277
927k
    if (F(n).left) {
278
442k
        n = F(n).left;
279
791k
        while (F(n).right)
280
349k
            n = F(n).right;
281
485k
    } else {
282
485k
        uint y = F(n).parent;
283
933k
        while (F(n).parent && n == F(y).left) {
284
448k
            n = y;
285
448k
            y = F(y).parent;
286
448k
        }
287
485k
        n = y;
288
485k
    }
289
927k
    return n;
290
927k
}
QFragmentMapData<QTextFragmentData>::previous(unsigned int) const
Line
Count
Source
273
113k
uint QFragmentMapData<Fragment>::previous(uint n) const {
274
113k
    if (!n)
275
0
        return maximum(root());
276
277
113k
    if (F(n).left) {
278
38.9k
        n = F(n).left;
279
38.9k
        while (F(n).right)
280
0
            n = F(n).right;
281
74.5k
    } else {
282
74.5k
        uint y = F(n).parent;
283
149k
        while (F(n).parent && n == F(y).left) {
284
74.5k
            n = y;
285
74.5k
            y = F(y).parent;
286
74.5k
        }
287
74.5k
        n = y;
288
74.5k
    }
289
113k
    return n;
290
113k
}
QFragmentMapData<QTextBlockData>::previous(unsigned int) const
Line
Count
Source
273
814k
uint QFragmentMapData<Fragment>::previous(uint n) const {
274
814k
    if (!n)
275
0
        return maximum(root());
276
277
814k
    if (F(n).left) {
278
403k
        n = F(n).left;
279
752k
        while (F(n).right)
280
349k
            n = F(n).right;
281
410k
    } else {
282
410k
        uint y = F(n).parent;
283
784k
        while (F(n).parent && n == F(y).left) {
284
373k
            n = y;
285
373k
            y = F(y).parent;
286
373k
        }
287
410k
        n = y;
288
410k
    }
289
814k
    return n;
290
814k
}
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
848k
{
303
848k
    uint p = F(x).parent;
304
848k
    uint y = F(x).right;
305
306
307
848k
    if (y) {
308
848k
        F(x).right = F(y).left;
309
848k
        if (F(y).left)
310
394k
            F(F(y).left).parent = x;
311
848k
        F(y).left = x;
312
848k
        F(y).parent = p;
313
848k
    } else {
314
0
        F(x).right = 0;
315
0
    }
316
848k
    if (!p) {
317
26.6k
        Q_ASSERT(head->root == x);
318
26.6k
        head->root = y;
319
26.6k
    }
320
821k
    else if (x == F(p).left)
321
252k
        F(p).left = y;
322
569k
    else
323
569k
        F(p).right = y;
324
848k
    F(x).parent = y;
325
2.44M
    for (uint field = 0; field < Fragment::size_array_max; ++field)
326
1.60M
        F(y).size_left_array[field] += F(x).size_left_array[field] + F(x).size_array[field];
327
848k
}
QFragmentMapData<QTextFragmentData>::rotateLeft(unsigned int)
Line
Count
Source
302
472k
{
303
472k
    uint p = F(x).parent;
304
472k
    uint y = F(x).right;
305
306
307
472k
    if (y) {
308
472k
        F(x).right = F(y).left;
309
472k
        if (F(y).left)
310
219k
            F(F(y).left).parent = x;
311
472k
        F(y).left = x;
312
472k
        F(y).parent = p;
313
472k
    } else {
314
0
        F(x).right = 0;
315
0
    }
316
472k
    if (!p) {
317
11.8k
        Q_ASSERT(head->root == x);
318
11.8k
        head->root = y;
319
11.8k
    }
320
460k
    else if (x == F(p).left)
321
252k
        F(p).left = y;
322
207k
    else
323
207k
        F(p).right = y;
324
472k
    F(x).parent = y;
325
944k
    for (uint field = 0; field < Fragment::size_array_max; ++field)
326
472k
        F(y).size_left_array[field] += F(x).size_left_array[field] + F(x).size_array[field];
327
472k
}
QFragmentMapData<QTextBlockData>::rotateLeft(unsigned int)
Line
Count
Source
302
376k
{
303
376k
    uint p = F(x).parent;
304
376k
    uint y = F(x).right;
305
306
307
376k
    if (y) {
308
376k
        F(x).right = F(y).left;
309
376k
        if (F(y).left)
310
174k
            F(F(y).left).parent = x;
311
376k
        F(y).left = x;
312
376k
        F(y).parent = p;
313
376k
    } else {
314
0
        F(x).right = 0;
315
0
    }
316
376k
    if (!p) {
317
14.7k
        Q_ASSERT(head->root == x);
318
14.7k
        head->root = y;
319
14.7k
    }
320
361k
    else if (x == F(p).left)
321
0
        F(p).left = y;
322
361k
    else
323
361k
        F(p).right = y;
324
376k
    F(x).parent = y;
325
1.50M
    for (uint field = 0; field < Fragment::size_array_max; ++field)
326
1.12M
        F(y).size_left_array[field] += F(x).size_left_array[field] + F(x).size_array[field];
327
376k
}
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
252k
{
340
252k
    uint y = F(x).left;
341
252k
    uint p = F(x).parent;
342
343
252k
    if (y) {
344
252k
        F(x).left = F(y).right;
345
252k
        if (F(y).right)
346
0
            F(F(y).right).parent = x;
347
252k
        F(y).right = x;
348
252k
        F(y).parent = p;
349
252k
    } else {
350
0
        F(x).left = 0;
351
0
    }
352
252k
    if (!p) {
353
6.77k
        Q_ASSERT(head->root == x);
354
6.77k
        head->root = y;
355
6.77k
    }
356
245k
    else if (x == F(p).right)
357
245k
        F(p).right = y;
358
0
    else
359
0
        F(p).left = y;
360
252k
    F(x).parent = y;
361
505k
    for (uint field = 0; field < Fragment::size_array_max; ++field)
362
252k
        F(x).size_left_array[field] -= F(y).size_left_array[field] + F(y).size_array[field];
363
252k
}
QFragmentMapData<QTextFragmentData>::rotateRight(unsigned int)
Line
Count
Source
339
252k
{
340
252k
    uint y = F(x).left;
341
252k
    uint p = F(x).parent;
342
343
252k
    if (y) {
344
252k
        F(x).left = F(y).right;
345
252k
        if (F(y).right)
346
0
            F(F(y).right).parent = x;
347
252k
        F(y).right = x;
348
252k
        F(y).parent = p;
349
252k
    } else {
350
0
        F(x).left = 0;
351
0
    }
352
252k
    if (!p) {
353
6.77k
        Q_ASSERT(head->root == x);
354
6.77k
        head->root = y;
355
6.77k
    }
356
245k
    else if (x == F(p).right)
357
245k
        F(p).right = y;
358
0
    else
359
0
        F(p).left = y;
360
252k
    F(x).parent = y;
361
505k
    for (uint field = 0; field < Fragment::size_array_max; ++field)
362
252k
        F(x).size_left_array[field] -= F(y).size_left_array[field] + F(y).size_array[field];
363
252k
}
Unexecuted instantiation: QFragmentMapData<QTextBlockData>::rotateRight(unsigned int)
364
365
366
template <class Fragment>
367
void QFragmentMapData<Fragment>::rebalance(uint x)
368
962k
{
369
962k
    F(x).color = Red;
370
371
2.64M
    while (F(x).parent && F(F(x).parent).color == Red) {
372
1.68M
        uint p = F(x).parent;
373
1.68M
        uint pp = F(p).parent;
374
1.68M
        Q_ASSERT(pp);
375
1.68M
        if (p == F(pp).left) {
376
252k
            uint y = F(pp).right;
377
252k
            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
252k
            } else {
383
252k
                if (x == F(p).right) {
384
252k
                    x = p;
385
252k
                    rotateLeft(x);
386
252k
                    p = F(x).parent;
387
252k
                    pp = F(p).parent;
388
252k
                }
389
252k
                F(p).color = Black;
390
252k
                if (pp) {
391
252k
                    F(pp).color = Red;
392
252k
                    rotateRight(pp);
393
252k
                }
394
252k
            }
395
1.42M
        } else {
396
1.42M
            uint y = F(pp).left;
397
1.42M
            if (y && F(y).color == Red) {
398
832k
                F(p).color = Black;
399
832k
                F(y).color = Black;
400
832k
                F(pp).color = Red;
401
832k
                x = pp;
402
832k
            } else {
403
595k
                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
595k
                F(p).color = Black;
410
595k
                if (pp) {
411
595k
                    F(pp).color = Red;
412
595k
                    rotateLeft(pp);
413
595k
                }
414
595k
            }
415
1.42M
        }
416
1.68M
    }
417
962k
    F(root()).color = Black;
418
962k
}
QFragmentMapData<QTextFragmentData>::rebalance(unsigned int)
Line
Count
Source
368
538k
{
369
538k
    F(x).color = Red;
370
371
1.47M
    while (F(x).parent && F(F(x).parent).color == Red) {
372
935k
        uint p = F(x).parent;
373
935k
        uint pp = F(p).parent;
374
935k
        Q_ASSERT(pp);
375
935k
        if (p == F(pp).left) {
376
252k
            uint y = F(pp).right;
377
252k
            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
252k
            } else {
383
252k
                if (x == F(p).right) {
384
252k
                    x = p;
385
252k
                    rotateLeft(x);
386
252k
                    p = F(x).parent;
387
252k
                    pp = F(p).parent;
388
252k
                }
389
252k
                F(p).color = Black;
390
252k
                if (pp) {
391
252k
                    F(pp).color = Red;
392
252k
                    rotateRight(pp);
393
252k
                }
394
252k
            }
395
683k
        } else {
396
683k
            uint y = F(pp).left;
397
683k
            if (y && F(y).color == Red) {
398
463k
                F(p).color = Black;
399
463k
                F(y).color = Black;
400
463k
                F(pp).color = Red;
401
463k
                x = pp;
402
463k
            } else {
403
219k
                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
219k
                F(p).color = Black;
410
219k
                if (pp) {
411
219k
                    F(pp).color = Red;
412
219k
                    rotateLeft(pp);
413
219k
                }
414
219k
            }
415
683k
        }
416
935k
    }
417
538k
    F(root()).color = Black;
418
538k
}
QFragmentMapData<QTextBlockData>::rebalance(unsigned int)
Line
Count
Source
368
424k
{
369
424k
    F(x).color = Red;
370
371
1.16M
    while (F(x).parent && F(F(x).parent).color == Red) {
372
744k
        uint p = F(x).parent;
373
744k
        uint pp = F(p).parent;
374
744k
        Q_ASSERT(pp);
375
744k
        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
744k
        } else {
396
744k
            uint y = F(pp).left;
397
744k
            if (y && F(y).color == Red) {
398
368k
                F(p).color = Black;
399
368k
                F(y).color = Black;
400
368k
                F(pp).color = Red;
401
368k
                x = pp;
402
376k
            } else {
403
376k
                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
376k
                F(p).color = Black;
410
376k
                if (pp) {
411
376k
                    F(pp).color = Red;
412
376k
                    rotateLeft(pp);
413
376k
                }
414
376k
            }
415
744k
        }
416
744k
    }
417
424k
    F(root()).color = Black;
418
424k
}
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
11.7M
{
601
11.7M
    Q_ASSERT(field < Fragment::size_array_max);
602
11.7M
    uint x = root();
603
604
11.7M
    uint s = k;
605
83.4M
    while (x) {
606
82.3M
        if (sizeLeft(x, field) <= s) {
607
65.6M
            if (s < sizeLeft(x, field) + size(x, field))
608
10.6M
                return x;
609
54.9M
            s -= sizeLeft(x, field) + size(x, field);
610
54.9M
            x = F(x).right;
611
54.9M
        } else {
612
16.7M
            x = F(x).left;
613
16.7M
        }
614
82.3M
    }
615
1.06M
    return 0;
616
11.7M
}
QFragmentMapData<QTextFragmentData>::findNode(int, unsigned int) const
Line
Count
Source
600
9.20M
{
601
9.20M
    Q_ASSERT(field < Fragment::size_array_max);
602
9.20M
    uint x = root();
603
604
9.20M
    uint s = k;
605
61.2M
    while (x) {
606
61.2M
        if (sizeLeft(x, field) <= s) {
607
44.9M
            if (s < sizeLeft(x, field) + size(x, field))
608
9.17M
                return x;
609
35.7M
            s -= sizeLeft(x, field) + size(x, field);
610
35.7M
            x = F(x).right;
611
35.7M
        } else {
612
16.3M
            x = F(x).left;
613
16.3M
        }
614
61.2M
    }
615
34.8k
    return 0;
616
9.20M
}
QFragmentMapData<QTextBlockData>::findNode(int, unsigned int) const
Line
Count
Source
600
2.50M
{
601
2.50M
    Q_ASSERT(field < Fragment::size_array_max);
602
2.50M
    uint x = root();
603
604
2.50M
    uint s = k;
605
22.1M
    while (x) {
606
21.0M
        if (sizeLeft(x, field) <= s) {
607
20.6M
            if (s < sizeLeft(x, field) + size(x, field))
608
1.48M
                return x;
609
19.1M
            s -= sizeLeft(x, field) + size(x, field);
610
19.1M
            x = F(x).right;
611
19.1M
        } else {
612
404k
            x = F(x).left;
613
404k
        }
614
21.0M
    }
615
1.02M
    return 0;
616
2.50M
}
617
618
template <class Fragment>
619
uint QFragmentMapData<Fragment>::insert_single(int key, uint length)
620
962k
{
621
962k
    Q_ASSERT(!findNode(key) || (int)this->position(findNode(key)) == key);
622
623
962k
    uint z = createFragment();
624
625
962k
    F(z).left = 0;
626
962k
    F(z).right = 0;
627
962k
    F(z).size_array[0] = length;
628
1.81M
    for (uint field = 1; field < Fragment::size_array_max; ++field)
629
848k
        F(z).size_array[field] = 1;
630
2.77M
    for (uint field = 0; field < Fragment::size_array_max; ++field)
631
1.81M
        F(z).size_left_array[field] = 0;
632
633
962k
    uint y = 0;
634
962k
    uint x = root();
635
636
962k
    Q_ASSERT(!x || F(x).parent == 0);
637
638
962k
    uint s = key;
639
962k
    bool right = false;
640
11.1M
    while (x) {
641
10.2M
        y = x;
642
10.2M
        if (s <= F(x).size_left_array[0]) {
643
520k
            x = F(x).left;
644
520k
            right = false;
645
9.70M
        } else {
646
9.70M
            s -= F(x).size_left_array[0] + F(x).size_array[0];
647
9.70M
            x = F(x).right;
648
9.70M
            right = true;
649
9.70M
        }
650
10.2M
    }
651
652
962k
    F(z).parent = y;
653
962k
    if (!y) {
654
34.8k
        head->root = z;
655
927k
    } else if (!right) {
656
267k
        F(y).left = z;
657
535k
        for (uint field = 0; field < Fragment::size_array_max; ++field)
658
267k
            F(y).size_left_array[field] = F(z).size_array[field];
659
659k
    } else {
660
659k
        F(y).right = z;
661
659k
    }
662
10.2M
    while (y && F(y).parent) {
663
9.29M
        uint p = F(y).parent;
664
9.29M
        if (F(p).left == y) {
665
505k
            for (uint field = 0; field < Fragment::size_array_max; ++field)
666
252k
                F(p).size_left_array[field] += F(z).size_array[field];
667
252k
        }
668
9.29M
        y = p;
669
9.29M
    }
670
962k
    rebalance(z);
671
672
962k
    return z;
673
962k
}
QFragmentMapData<QTextFragmentData>::insert_single(int, unsigned int)
Line
Count
Source
620
538k
{
621
538k
    Q_ASSERT(!findNode(key) || (int)this->position(findNode(key)) == key);
622
623
538k
    uint z = createFragment();
624
625
538k
    F(z).left = 0;
626
538k
    F(z).right = 0;
627
538k
    F(z).size_array[0] = length;
628
538k
    for (uint field = 1; field < Fragment::size_array_max; ++field)
629
0
        F(z).size_array[field] = 1;
630
1.07M
    for (uint field = 0; field < Fragment::size_array_max; ++field)
631
538k
        F(z).size_left_array[field] = 0;
632
633
538k
    uint y = 0;
634
538k
    uint x = root();
635
636
538k
    Q_ASSERT(!x || F(x).parent == 0);
637
638
538k
    uint s = key;
639
538k
    bool right = false;
640
6.24M
    while (x) {
641
5.70M
        y = x;
642
5.70M
        if (s <= F(x).size_left_array[0]) {
643
520k
            x = F(x).left;
644
520k
            right = false;
645
5.18M
        } else {
646
5.18M
            s -= F(x).size_left_array[0] + F(x).size_array[0];
647
5.18M
            x = F(x).right;
648
5.18M
            right = true;
649
5.18M
        }
650
5.70M
    }
651
652
538k
    F(z).parent = y;
653
538k
    if (!y) {
654
17.4k
        head->root = z;
655
520k
    } else if (!right) {
656
267k
        F(y).left = z;
657
535k
        for (uint field = 0; field < Fragment::size_array_max; ++field)
658
267k
            F(y).size_left_array[field] = F(z).size_array[field];
659
267k
    } else {
660
252k
        F(y).right = z;
661
252k
    }
662
5.72M
    while (y && F(y).parent) {
663
5.18M
        uint p = F(y).parent;
664
5.18M
        if (F(p).left == y) {
665
505k
            for (uint field = 0; field < Fragment::size_array_max; ++field)
666
252k
                F(p).size_left_array[field] += F(z).size_array[field];
667
252k
        }
668
5.18M
        y = p;
669
5.18M
    }
670
538k
    rebalance(z);
671
672
538k
    return z;
673
538k
}
QFragmentMapData<QTextBlockData>::insert_single(int, unsigned int)
Line
Count
Source
620
424k
{
621
424k
    Q_ASSERT(!findNode(key) || (int)this->position(findNode(key)) == key);
622
623
424k
    uint z = createFragment();
624
625
424k
    F(z).left = 0;
626
424k
    F(z).right = 0;
627
424k
    F(z).size_array[0] = length;
628
1.27M
    for (uint field = 1; field < Fragment::size_array_max; ++field)
629
848k
        F(z).size_array[field] = 1;
630
1.69M
    for (uint field = 0; field < Fragment::size_array_max; ++field)
631
1.27M
        F(z).size_left_array[field] = 0;
632
633
424k
    uint y = 0;
634
424k
    uint x = root();
635
636
424k
    Q_ASSERT(!x || F(x).parent == 0);
637
638
424k
    uint s = key;
639
424k
    bool right = false;
640
4.94M
    while (x) {
641
4.51M
        y = x;
642
4.51M
        if (s <= F(x).size_left_array[0]) {
643
0
            x = F(x).left;
644
0
            right = false;
645
4.51M
        } else {
646
4.51M
            s -= F(x).size_left_array[0] + F(x).size_array[0];
647
4.51M
            x = F(x).right;
648
4.51M
            right = true;
649
4.51M
        }
650
4.51M
    }
651
652
424k
    F(z).parent = y;
653
424k
    if (!y) {
654
17.4k
        head->root = z;
655
407k
    } 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
407k
    } else {
660
407k
        F(y).right = z;
661
407k
    }
662
4.53M
    while (y && F(y).parent) {
663
4.11M
        uint p = F(y).parent;
664
4.11M
        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
4.11M
        y = p;
669
4.11M
    }
670
424k
    rebalance(z);
671
672
424k
    return z;
673
424k
}
674
675
676
template <class Fragment>
677
5.00M
int QFragmentMapData<Fragment>::length(uint field) const {
678
5.00M
    uint root = this->root();
679
5.00M
    return root ? sizeLeft(root, field) + size(root, field) + sizeRight(root, field) : 0;
680
5.00M
}
QFragmentMapData<QTextFragmentData>::length(unsigned int) const
Line
Count
Source
677
2.34M
int QFragmentMapData<Fragment>::length(uint field) const {
678
2.34M
    uint root = this->root();
679
2.34M
    return root ? sizeLeft(root, field) + size(root, field) + sizeRight(root, field) : 0;
680
2.34M
}
QFragmentMapData<QTextBlockData>::length(unsigned int) const
Line
Count
Source
677
2.66M
int QFragmentMapData<Fragment>::length(uint field) const {
678
2.66M
    uint root = this->root();
679
2.66M
    return root ? sizeLeft(root, field) + size(root, field) + sizeRight(root, field) : 0;
680
2.66M
}
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
34.8k
        Iterator(QFragmentMap *p, int node) : pt(p), n(node) {}
QFragmentMap<QTextBlockData>::Iterator::Iterator(QFragmentMap<QTextBlockData>*, int)
Line
Count
Source
694
17.4k
        Iterator(QFragmentMap *p, int node) : pt(p), n(node) {}
QFragmentMap<QTextFragmentData>::Iterator::Iterator(QFragmentMap<QTextFragmentData>*, int)
Line
Count
Source
694
17.4k
        Iterator(QFragmentMap *p, int node) : pt(p), n(node) {}
695
        Iterator(const Iterator& it) : pt(it.pt), n(it.n) {}
696
697
1.95M
        inline bool atEnd() const { return !n; }
QFragmentMap<QTextBlockData>::Iterator::atEnd() const
Line
Count
Source
697
866k
        inline bool atEnd() const { return !n; }
QFragmentMap<QTextFragmentData>::Iterator::atEnd() const
Line
Count
Source
697
1.09M
        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
962k
        Fragment *value() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
QFragmentMap<QTextBlockData>::Iterator::value()
Line
Count
Source
710
424k
        Fragment *value() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
QFragmentMap<QTextFragmentData>::Iterator::value()
Line
Count
Source
710
538k
        Fragment *value() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
711
712
962k
        Iterator& operator++() {
713
962k
            n = pt->data.next(n);
714
962k
            return *this;
715
962k
        }
QFragmentMap<QTextBlockData>::Iterator::operator++()
Line
Count
Source
712
424k
        Iterator& operator++() {
713
424k
            n = pt->data.next(n);
714
424k
            return *this;
715
424k
        }
QFragmentMap<QTextFragmentData>::Iterator::operator++()
Line
Count
Source
712
538k
        Iterator& operator++() {
713
538k
            n = pt->data.next(n);
714
538k
            return *this;
715
538k
        }
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
7.63M
        ConstIterator(const QFragmentMap *p, int node) : pt(p), n(node) {}
QFragmentMap<QTextFragmentData>::ConstIterator::ConstIterator(QFragmentMap<QTextFragmentData> const*, int)
Line
Count
Source
734
7.61M
        ConstIterator(const QFragmentMap *p, int node) : pt(p), n(node) {}
QFragmentMap<QTextBlockData>::ConstIterator::ConstIterator(QFragmentMap<QTextBlockData> const*, int)
Line
Count
Source
734
17.4k
        ConstIterator(const QFragmentMap *p, int node) : pt(p), n(node) {}
735
        ConstIterator(const ConstIterator& it) : pt(it.pt), n(it.n) {}
736
        ConstIterator(const Iterator& it) : pt(it.pt), n(it.n) {}
737
738
4.90M
        inline bool atEnd() const { return !n; }
739
740
821k
        bool operator==(const ConstIterator& it) const { return pt == it.pt && n == it.n; }
741
2.24M
        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
598k
        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
4.30M
        const Fragment *value() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
750
751
774k
        ConstIterator& operator++() {
752
774k
            n = pt->data.next(n);
753
774k
            return *this;
754
774k
        }
755
        ConstIterator& operator--() {
756
            n = pt->data.previous(n);
757
            return *this;
758
        }
759
    };
760
761
762
34.8k
    QFragmentMap() {}
QFragmentMap<QTextFragmentData>::QFragmentMap()
Line
Count
Source
762
17.4k
    QFragmentMap() {}
QFragmentMap<QTextBlockData>::QFragmentMap()
Line
Count
Source
762
17.4k
    QFragmentMap() {}
763
    ~QFragmentMap()
764
34.8k
    {
765
34.8k
        if (!data.fragments)
766
0
            return; // in case of out-of-memory, we won't have fragments
767
997k
        for (Iterator it = begin(); !it.atEnd(); ++it)
768
962k
            it.value()->free();
769
34.8k
    }
QFragmentMap<QTextFragmentData>::~QFragmentMap()
Line
Count
Source
764
17.4k
    {
765
17.4k
        if (!data.fragments)
766
0
            return; // in case of out-of-memory, we won't have fragments
767
555k
        for (Iterator it = begin(); !it.atEnd(); ++it)
768
538k
            it.value()->free();
769
17.4k
    }
QFragmentMap<QTextBlockData>::~QFragmentMap()
Line
Count
Source
764
17.4k
    {
765
17.4k
        if (!data.fragments)
766
0
            return; // in case of out-of-memory, we won't have fragments
767
441k
        for (Iterator it = begin(); !it.atEnd(); ++it)
768
424k
            it.value()->free();
769
17.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
34.8k
    inline Iterator begin() { return Iterator(this, data.minimum(data.root())); }
QFragmentMap<QTextBlockData>::begin()
Line
Count
Source
777
17.4k
    inline Iterator begin() { return Iterator(this, data.minimum(data.root())); }
QFragmentMap<QTextFragmentData>::begin()
Line
Count
Source
777
17.4k
    inline Iterator begin() { return Iterator(this, data.minimum(data.root())); }
778
    inline Iterator end() { return Iterator(this, 0); }
779
17.4k
    inline ConstIterator begin() const { return ConstIterator(this, data.minimum(data.root())); }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::begin() const
QFragmentMap<QTextBlockData>::begin() const
Line
Count
Source
779
17.4k
    inline ConstIterator begin() const { return ConstIterator(this, data.minimum(data.root())); }
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
111k
    inline int numNodes() const { return data.head->node_count; }
786
5.00M
    int length(uint field = 0) const { return data.length(field); }
QFragmentMap<QTextFragmentData>::length(unsigned int) const
Line
Count
Source
786
2.34M
    int length(uint field = 0) const { return data.length(field); }
QFragmentMap<QTextBlockData>::length(unsigned int) const
Line
Count
Source
786
2.66M
    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
7.61M
    ConstIterator find(int k, uint field = 0) const { return ConstIterator(this, data.findNode(k, field)); }
790
791
2.62M
    uint findNode(int k, uint field = 0) const { return data.findNode(k, field); }
QFragmentMap<QTextBlockData>::findNode(int, unsigned int) const
Line
Count
Source
791
2.08M
    uint findNode(int k, uint field = 0) const { return data.findNode(k, field); }
QFragmentMap<QTextFragmentData>::findNode(int, unsigned int) const
Line
Count
Source
791
538k
    uint findNode(int k, uint field = 0) const { return data.findNode(k, field); }
792
793
    uint insert_single(int key, uint length)
794
962k
    {
795
962k
        uint f = data.insert_single(key, length);
796
962k
        if (f != 0) {
797
962k
            Fragment *frag = fragment(f);
798
962k
            Q_ASSERT(frag);
799
962k
            frag->initialize();
800
962k
        }
801
962k
        return f;
802
962k
    }
QFragmentMap<QTextFragmentData>::insert_single(int, unsigned int)
Line
Count
Source
794
538k
    {
795
538k
        uint f = data.insert_single(key, length);
796
538k
        if (f != 0) {
797
538k
            Fragment *frag = fragment(f);
798
            Q_ASSERT(frag);
799
538k
            frag->initialize();
800
538k
        }
801
538k
        return f;
802
538k
    }
QFragmentMap<QTextBlockData>::insert_single(int, unsigned int)
Line
Count
Source
794
424k
    {
795
424k
        uint f = data.insert_single(key, length);
796
424k
        if (f != 0) {
797
424k
            Fragment *frag = fragment(f);
798
            Q_ASSERT(frag);
799
424k
            frag->initialize();
800
424k
        }
801
424k
        return f;
802
424k
    }
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
15.5M
    inline Fragment *fragment(uint index) {
814
15.5M
        Q_ASSERT(index != 0);
815
15.5M
        return data.fragment(index);
816
15.5M
    }
QFragmentMap<QTextBlockData>::fragment(unsigned int)
Line
Count
Source
813
13.7M
    inline Fragment *fragment(uint index) {
814
        Q_ASSERT(index != 0);
815
13.7M
        return data.fragment(index);
816
13.7M
    }
QFragmentMap<QTextFragmentData>::fragment(unsigned int)
Line
Count
Source
813
1.80M
    inline Fragment *fragment(uint index) {
814
        Q_ASSERT(index != 0);
815
1.80M
        return data.fragment(index);
816
1.80M
    }
817
4.90M
    inline const Fragment *fragment(uint index) const {
818
4.90M
        Q_ASSERT(index != 0);
819
4.90M
        return data.fragment(index);
820
4.90M
    }
QFragmentMap<QTextFragmentData>::fragment(unsigned int) const
Line
Count
Source
817
4.90M
    inline const Fragment *fragment(uint index) const {
818
        Q_ASSERT(index != 0);
819
4.90M
        return data.fragment(index);
820
4.90M
    }
Unexecuted instantiation: QFragmentMap<QTextBlockData>::fragment(unsigned int) const
821
11.1M
    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
10.6M
    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
520k
    inline uint position(uint node, uint field = 0) const { return data.position(node, field); }
822
8.32M
    inline bool isValid(uint n) const { return data.isValid(n); }
823
4.70M
    inline uint next(uint n) const { return data.next(n); }
QFragmentMap<QTextBlockData>::next(unsigned int) const
Line
Count
Source
823
4.61M
    inline uint next(uint n) const { return data.next(n); }
QFragmentMap<QTextFragmentData>::next(unsigned int) const
Line
Count
Source
823
96.2k
    inline uint next(uint n) const { return data.next(n); }
824
927k
    inline uint previous(uint n) const { return data.previous(n); }
QFragmentMap<QTextFragmentData>::previous(unsigned int) const
Line
Count
Source
824
113k
    inline uint previous(uint n) const { return data.previous(n); }
QFragmentMap<QTextBlockData>::previous(unsigned int) const
Line
Count
Source
824
814k
    inline uint previous(uint n) const { return data.previous(n); }
825
6.91M
    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
6.91M
    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
113k
        { data.setSize(node, new_size, field);
828
113k
      if (node != 0 && field == 0) {
829
113k
          Fragment *frag = fragment(node);
830
113k
          Q_ASSERT(frag);
831
113k
          frag->invalidate();
832
113k
      }
833
113k
    }
QFragmentMap<QTextBlockData>::setSize(unsigned int, int, unsigned int)
Line
Count
Source
827
113k
        { data.setSize(node, new_size, field);
828
113k
      if (node != 0 && field == 0) {
829
113k
          Fragment *frag = fragment(node);
830
          Q_ASSERT(frag);
831
113k
          frag->invalidate();
832
113k
      }
833
113k
    }
Unexecuted instantiation: QFragmentMap<QTextFragmentData>::setSize(unsigned int, int, unsigned int)
834
835
17.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