1
/****************************************************************************
2
**
3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the QtGui module of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
#ifndef QFRAGMENTMAP_P_H
43
#define QFRAGMENTMAP_P_H
44
45
//
46
//  W A R N I N G
47
//  -------------
48
//
49
// This file is not part of the Qt API.  It exists purely as an
50
// implementation detail.  This header file may change from version to
51
// version without notice, or even be removed.
52
//
53
// We mean it.
54
//
55
56
#include "QtCore/qglobal.h"
57
#include <stdlib.h>
58
#include <private/qtools_p.h>
59
60
QT_BEGIN_NAMESPACE
61
62
63
template <int N = 1>
64
class QFragment
65
{
66
public:
67
    quint32 parent;
68
    quint32 left;
69
    quint32 right;
70
    quint32 color;
71
    quint32 size_left_array[N];
72
    quint32 size_array[N];
73
    enum {size_array_max = N };
74
};
75
76
template <class Fragment>
77
class QFragmentMapData
78
{
79
    enum Color { Red, Black };
80
public:
81
    QFragmentMapData();
82
    ~QFragmentMapData();
83
84
    void init();
85
86
    class Header
87
    {
88
    public:
89
        quint32 root; // this relies on being at the same position as parent in the fragment struct
90
        quint32 tag;
91
        quint32 freelist;
92
        quint32 node_count;
93
        quint32 allocated;
94
    };
95
96
97
    enum {fragmentSize = sizeof(Fragment) };
98
99
100
    int length(uint field = 0) const;
101
102
103
    inline Fragment *fragment(uint index) {
104
        return (fragments + index);
105
    }
106
    inline const Fragment *fragment(uint index) const {
107
        return (fragments + index);
108
    }
109
110
111
    inline Fragment &F(uint index) { return fragments[index] ; }
112
    inline const Fragment &F(uint index) const { return fragments[index] ; }
113
114
    inline bool isRoot(uint index) const {
115
        return !fragment(index)->parent;
116
    }
117
118
    inline uint position(uint node, uint field = 0) const {
119
        Q_ASSERT(field < Fragment::size_array_max);
120
        const Fragment *f = fragment(node);
121
        uint offset = f->size_left_array[field];
122
        while (f->parent) {
123
            uint p = f->parent;
124
            f = fragment(p);
125
            if (f->right == node)
126
                offset += f->size_left_array[field] + f->size_array[field];
127
            node = p;
128
        }
129
        return offset;
130
    }
131
    inline uint sizeRight(uint node, uint field = 0) const {
132
        Q_ASSERT(field < Fragment::size_array_max);
133
        uint sr = 0;
134
        const Fragment *f = fragment(node);
135
        node = f->right;
136
        while (node) {
137
            f = fragment(node);
138
            sr += f->size_left_array[field] + f->size_array[field];
139
            node = f->right;
140
        }
141
        return sr;
142
    }
143
    inline uint sizeLeft(uint node, uint field = 0) const {
144
        Q_ASSERT(field < Fragment::size_array_max);
145
        return fragment(node)->size_left_array[field];
146
    }
147
148
149
    inline uint size(uint node, uint field = 0) const {
150
        Q_ASSERT(field < Fragment::size_array_max);
151
        return fragment(node)->size_array[field];
152
    }
153
154
    inline void setSize(uint node, int new_size, uint field = 0) {
155
        Q_ASSERT(field < Fragment::size_array_max);
156
        Fragment *f = fragment(node);
157
        int diff = new_size - f->size_array[field];
158
        f->size_array[field] = new_size;
159
        while (f->parent) {
160
            uint p = f->parent;
161
            f = fragment(p);
162
            if (f->left == node)
163
                f->size_left_array[field] += diff;
164
            node = p;
165
        }
166
    }
167
168
169
    uint findNode(int k, uint field = 0) const;
170
171
    uint insert_single(int key, uint length);
172
    uint erase_single(uint f);
173
174
    uint minimum(uint n) const {
175
        while (n && fragment(n)->left)
176
            n = fragment(n)->left;
177
        return n;
178
    }
179
180
    uint maximum(uint n) const {
181
        while (n && fragment(n)->right)
182
            n = fragment(n)->right;
183
        return n;
184
    }
185
186
    uint next(uint n) const;
187
    uint previous(uint n) const;
188
189
    inline uint root() const {
190
        Q_ASSERT(!head->root || !fragment(head->root)->parent);
191
        return head->root;
192
    }
193
    inline void setRoot(uint new_root) {
194
        Q_ASSERT(!head->root || !fragment(new_root)->parent);
195
        head->root = new_root;
196
    }
197
198
    inline bool isValid(uint n) const {
199
        return n > 0 && n != head->freelist;
200
    }
201
202
    union {
203
        Header *head;
204
        Fragment *fragments;
205
    };
206
207
private:
208
209
    void rotateLeft(uint x);
210
    void rotateRight(uint x);
211
    void rebalance(uint x);
212
    void removeAndRebalance(uint z);
213
214
    uint createFragment();
215
    void freeFragment(uint f);
216
217
};
218
219
template <class Fragment>
220
QFragmentMapData<Fragment>::QFragmentMapData()
221
    : fragments(0)
222
{
223
    init();
224
}
225
226
template <class Fragment>
227
void QFragmentMapData<Fragment>::init()
228
{
229
    // the following code will realloc an existing fragment or create a new one.
230
    // it will also ignore errors when shrinking an existing fragment.
231
    Fragment *newFragments = (Fragment *)realloc(fragments, 64*fragmentSize);
232
    if (newFragments) {
233
        fragments = newFragments;
234
        head->allocated = 64;
235
    }
236
    Q_CHECK_PTR(fragments);
237
238
    head->tag = (((quint32)'p') << 24) | (((quint32)'m') << 16) | (((quint32)'a') << 8) | 'p'; //TAG('p', 'm', 'a', 'p');
239
    head->root = 0;
240
    head->freelist = 1;
241
    head->node_count = 0;
242
    // mark all items to the right as unused
243
    F(head->freelist).right = 0;
244
}
245
246
template <class Fragment>
247
QFragmentMapData<Fragment>::~QFragmentMapData()
248
{
249
    free(fragments);
250
}
251
252
template <class Fragment>
253
uint QFragmentMapData<Fragment>::createFragment()
254
{
255
    Q_ASSERT(head->freelist <= head->allocated);
256
257
    uint freePos = head->freelist;
258
    if (freePos == head->allocated) {
259
        // need to create some free space
260
        uint needed = qAllocMore((freePos+1)*fragmentSize, 0);
261
        Q_ASSERT(needed/fragmentSize > head->allocated);
262
        Fragment *newFragments = (Fragment *)realloc(fragments, needed);
263
        Q_CHECK_PTR(newFragments);
264
        fragments = newFragments;
265
        head->allocated = needed/fragmentSize;
266
        F(freePos).right = 0;
267
    }
268
269
    uint nextPos = F(freePos).right;
270
    if (!nextPos) {
271
        nextPos = freePos+1;
272
        if (nextPos < head->allocated)
273
            F(nextPos).right = 0;
274
    }
275
276
    head->freelist = nextPos;
277
278
    ++head->node_count;
279
280
    return freePos;
281
}
282
283
template <class Fragment>
284
void QFragmentMapData<Fragment>::freeFragment(uint i)
285
{
286
    F(i).right = head->freelist;
287
    head->freelist = i;
288
289
    --head->node_count;
290
}
291
292
293
template <class Fragment>
294
uint QFragmentMapData<Fragment>::next(uint n) const {
295
    Q_ASSERT(n);
296
    if (F(n).right) {
297
        n = F(n).right;
298
        while (F(n).left)
299
            n = F(n).left;
300
    } else {
301
        uint y = F(n).parent;
302
        while (F(n).parent && n == F(y).right) {
303
            n = y;
304
            y = F(y).parent;
305
        }
306
        n = y;
307
    }
308
    return n;
309
}
310
311
template <class Fragment>
312
uint QFragmentMapData<Fragment>::previous(uint n) const {
313
    if (!n)
314
        return maximum(root());
315
316
    if (F(n).left) {
317
        n = F(n).left;
318
        while (F(n).right)
319
            n = F(n).right;
320
    } else {
321
        uint y = F(n).parent;
322
        while (F(n).parent && n == F(y).left) {
323
            n = y;
324
            y = F(y).parent;
325
        }
326
        n = y;
327
    }
328
    return n;
329
}
330
331
332
/*
333
     x              y
334
      \            / \
335
       y    -->   x   b
336
      / \          \
337
     a   b          a
338
*/
339
template <class Fragment>
340
void QFragmentMapData<Fragment>::rotateLeft(uint x)
341
{
342
    uint p = F(x).parent;
343
    uint y = F(x).right;
344
345
346
    if (y) {
347
        F(x).right = F(y).left;
348
        if (F(y).left)
349
            F(F(y).left).parent = x;
350
        F(y).left = x;
351
        F(y).parent = p;
352
    } else {
353
        F(x).right = 0;
354
    }
355
    if (!p) {
356
        Q_ASSERT(head->root == x);
357
        head->root = y;
358
    }
359
    else if (x == F(p).left)
360
        F(p).left = y;
361
    else
362
        F(p).right = y;
363
    F(x).parent = y;
364
    for (uint field = 0; field < Fragment::size_array_max; ++field)
365
        F(y).size_left_array[field] += F(x).size_left_array[field] + F(x).size_array[field];
366
}
367
368
369
/*
370
         x          y
371
        /          / \
372
       y    -->   a   x
373
      / \            /
374
     a   b          b
375
*/
376
template <class Fragment>
377
void QFragmentMapData<Fragment>::rotateRight(uint x)
378
{
379
    uint y = F(x).left;
380
    uint p = F(x).parent;
381
382
    if (y) {
383
        F(x).left = F(y).right;
384
        if (F(y).right)
385
            F(F(y).right).parent = x;
386
        F(y).right = x;
387
        F(y).parent = p;
388
    } else {
389
        F(x).left = 0;
390
    }
391
    if (!p) {
392
        Q_ASSERT(head->root == x);
393
        head->root = y;
394
    }
395
    else if (x == F(p).right)
396
        F(p).right = y;
397
    else
398
        F(p).left = y;
399
    F(x).parent = y;
400
    for (uint field = 0; field < Fragment::size_array_max; ++field)
401
        F(x).size_left_array[field] -= F(y).size_left_array[field] + F(y).size_array[field];
402
}
403
404
405
template <class Fragment>
406
void QFragmentMapData<Fragment>::rebalance(uint x)
407
{
408
    F(x).color = Red;
409
410
    while (F(x).parent && F(F(x).parent).color == Red) {
411
        uint p = F(x).parent;
412
        uint pp = F(p).parent;
413
        Q_ASSERT(pp);
414
        if (p == F(pp).left) {
415
            uint y = F(pp).right;
416
            if (y && F(y).color == Red) {
417
                F(p).color = Black;
418
                F(y).color = Black;
419
                F(pp).color = Red;
420
                x = pp;
421
            } else {
422
                if (x == F(p).right) {
423
                    x = p;
424
                    rotateLeft(x);
425
                    p = F(x).parent;
426
                    pp = F(p).parent;
427
                }
428
                F(p).color = Black;
429
                if (pp) {
430
                    F(pp).color = Red;
431
                    rotateRight(pp);
432
                }
433
            }
434
        } else {
435
            uint y = F(pp).left;
436
            if (y && F(y).color == Red) {
437
                F(p).color = Black;
438
                F(y).color = Black;
439
                F(pp).color = Red;
440
                x = pp;
441
            } else {
442
                if (x == F(p).left) {
443
                    x = p;
444
                    rotateRight(x);
445
                    p = F(x).parent;
446
                    pp = F(p).parent;
447
                }
448
                F(p).color = Black;
449
                if (pp) {
450
                    F(pp).color = Red;
451
                    rotateLeft(pp);
452
                }
453
            }
454
        }
455
    }
456
    F(root()).color = Black;
457
}
458
459
460
template <class Fragment>
461
uint QFragmentMapData<Fragment>::erase_single(uint z)
462
{
463
    uint w = previous(z);
464
    uint y = z;
465
    uint x;
466
    uint p;
467
468
    if (!F(y).left) {
469
        x = F(y).right;
470
    } else if (!F(y).right) {
471
        x = F(y).left;
472
    } else {
473
        y = F(y).right;
474
        while (F(y).left)
475
            y = F(y).left;
476
        x = F(y).right;
477
    }
478
479
    if (y != z) {
480
        F(F(z).left).parent = y;
481
        F(y).left = F(z).left;
482
        for (uint field = 0; field < Fragment::size_array_max; ++field)
483
            F(y).size_left_array[field] = F(z).size_left_array[field];
484
        if (y != F(z).right) {
485
            /*
486
                     z                y
487
                    / \              / \
488
                   a   b            a   b
489
                      /                /
490
                    ...     -->      ...
491
                    /                /
492
                   y                x
493
                  / \
494
                 0   x
495
             */
496
            p = F(y).parent;
497
            if (x)
498
                F(x).parent = p;
499
            F(p).left = x;
500
            F(y).right = F(z).right;
501
            F(F(z).right).parent = y;
502
            uint n = p;
503
            while (n != y) {
504
                for (uint field = 0; field < Fragment::size_array_max; ++field)
505
                    F(n).size_left_array[field] -= F(y).size_array[field];
506
                n = F(n).parent;
507
            }
508
        } else {
509
            /*
510
                     z                y
511
                    / \              / \
512
                   a   y     -->    a   x
513
                      / \
514
                     0   x
515
             */
516
            p = y;
517
        }
518
        uint zp = F(z).parent;
519
        if (!zp) {
520
            Q_ASSERT(head->root == z);
521
            head->root = y;
522
        } else if (F(zp).left == z) {
523
            F(zp).left = y;
524
            for (uint field = 0; field < Fragment::size_array_max; ++field)
525
                F(zp).size_left_array[field] -= F(z).size_array[field];
526
        } else {
527
            F(zp).right = y;
528
        }
529
        F(y).parent = zp;
530
        // Swap the colors
531
        uint c = F(y).color;
532
        F(y).color = F(z).color;
533
        F(z).color = c;
534
        y = z;
535
    } else {
536
        /*
537
                p          p            p          p
538
               /          /              \          \
539
              z    -->   x                z  -->     x
540
              |                           |
541
              x                           x
542
         */
543
        p = F(z).parent;
544
        if (x)
545
            F(x).parent = p;
546
        if (!p) {
547
            Q_ASSERT(head->root == z);
548
            head->root = x;
549
        } else if (F(p).left == z) {
550
            F(p).left = x;
551
            for (uint field = 0; field < Fragment::size_array_max; ++field)
552
                F(p).size_left_array[field] -= F(z).size_array[field];
553
        } else {
554
            F(p).right = x;
555
        }
556
    }
557
    uint n = z;
558
    while (F(n).parent) {
559
        uint p = F(n).parent;
560
        if (F(p).left == n) {
561
            for (uint field = 0; field < Fragment::size_array_max; ++field)
562
                F(p).size_left_array[field] -= F(z).size_array[field];
563
        }
564
        n = p;
565
    }
566
567
    freeFragment(z);
568
569
570
    if (F(y).color != Red) {
571
        while (F(x).parent && (x == 0 || F(x).color == Black)) {
572
            if (x == F(p).left) {
573
                uint w = F(p).right;
574
                if (F(w).color == Red) {
575
                    F(w).color = Black;
576
                    F(p).color = Red;
577
                    rotateLeft(p);
578
                    w = F(p).right;
579
                }
580
                if ((F(w).left == 0 || F(F(w).left).color == Black) &&
581
                    (F(w).right == 0 || F(F(w).right).color == Black)) {
582
                    F(w).color = Red;
583
                    x = p;
584
                    p = F(x).parent;
585
                } else {
586
                    if (F(w).right == 0 || F(F(w).right).color == Black) {
587
                        if (F(w).left)
588
                            F(F(w).left).color = Black;
589
                        F(w).color = Red;
590
                        rotateRight(F(p).right);
591
                        w = F(p).right;
592
                    }
593
                    F(w).color = F(p).color;
594
                    F(p).color = Black;
595
                    if (F(w).right)
596
                        F(F(w).right).color = Black;
597
                    rotateLeft(p);
598
                    break;
599
                }
600
            } else {
601
                uint w = F(p).left;
602
                if (F(w).color == Red) {
603
                    F(w).color = Black;
604
                    F(p).color = Red;
605
                    rotateRight(p);
606
                    w = F(p).left;
607
                }
608
                if ((F(w).right == 0 || F(F(w).right).color == Black) &&
609
                    (F(w).left == 0 || F(F(w).left).color == Black)) {
610
                    F(w).color = Red;
611
                    x = p;
612
                    p = F(x).parent;
613
                } else {
614
                    if (F(w).left == 0 || F(F(w).left).color == Black) {
615
                        if (F(w).right)
616
                            F(F(w).right).color = Black;
617
                        F(w).color = Red;
618
                        rotateLeft(F(p).left);
619
                        w = F(p).left;
620
                    }
621
                    F(w).color = F(p).color;
622
                    F(p).color = Black;
623
                    if (F(w).left)
624
                        F(F(w).left).color = Black;
625
                    rotateRight(p);
626
                    break;
627
                }
628
            }
629
        }
630
        if (x)
631
            F(x).color = Black;
632
    }
633
634
    return w;
635
}
636
637
template <class Fragment>
638
uint QFragmentMapData<Fragment>::findNode(int k, uint field) const
639
{
640
    Q_ASSERT(field < Fragment::size_array_max);
641
    uint x = root();
642
643
    uint s = k;
644
    while (x) {
645
        if (sizeLeft(x, field) <= s) {
646
            if (s < sizeLeft(x, field) + size(x, field))
647
                return x;
648
            s -= sizeLeft(x, field) + size(x, field);
649
            x = F(x).right;
650
        } else {
651
            x = F(x).left;
652
        }
653
    }
654
    return 0;
655
}
656
657
template <class Fragment>
658
uint QFragmentMapData<Fragment>::insert_single(int key, uint length)
659
{
660
    Q_ASSERT(!findNode(key) || (int)this->position(findNode(key)) == key);
661
662
    uint z = createFragment();
663
664
    F(z).left = 0;
665
    F(z).right = 0;
666
    F(z).size_array[0] = length;
667
    for (uint field = 1; field < Fragment::size_array_max; ++field)
668
        F(z).size_array[field] = 1;
669
    for (uint field = 0; field < Fragment::size_array_max; ++field)
670
        F(z).size_left_array[field] = 0;
671
672
    uint y = 0;
673
    uint x = root();
674
675
    Q_ASSERT(!x || F(x).parent == 0);
676
677
    uint s = key;
678
    bool right = false;
679
    while (x) {
680
        y = x;
681
        if (s <= F(x).size_left_array[0]) {
682
            x = F(x).left;
683
            right = false;
684
        } else {
685
            s -= F(x).size_left_array[0] + F(x).size_array[0];
686
            x = F(x).right;
687
            right = true;
688
        }
689
    }
690
691
    F(z).parent = y;
692
    if (!y) {
693
        head->root = z;
694
    } else if (!right) {
695
        F(y).left = z;
696
        for (uint field = 0; field < Fragment::size_array_max; ++field)
697
            F(y).size_left_array[field] = F(z).size_array[field];
698
    } else {
699
        F(y).right = z;
700
    }
701
    while (y && F(y).parent) {
702
        uint p = F(y).parent;
703
        if (F(p).left == y) {
704
            for (uint field = 0; field < Fragment::size_array_max; ++field)
705
                F(p).size_left_array[field] += F(z).size_array[field];
706
        }
707
        y = p;
708
    }
709
    rebalance(z);
710
711
    return z;
712
}
713
714
715
template <class Fragment>
716
int QFragmentMapData<Fragment>::length(uint field) const {
717
    uint root = this->root();
718
    return root ? sizeLeft(root, field) + size(root, field) + sizeRight(root, field) : 0;
719
}
720
721
722
template <class Fragment> // NOTE: must inherit QFragment
723
class QFragmentMap
724
{
725
public:
726
    class Iterator
727
    {
728
    public:
729
        QFragmentMap *pt;
730
        quint32 n;
731
732
        Iterator() : pt(0), n(0) {}
733
        Iterator(QFragmentMap *p, int node) : pt(p), n(node) {}
734
        Iterator(const Iterator& it) : pt(it.pt), n(it.n) {}
735
736
        inline bool atEnd() const { return !n; }
737
738
        bool operator==(const Iterator& it) const { return pt == it.pt && n == it.n; }
739
        bool operator!=(const Iterator& it) const { return pt != it.pt || n != it.n; }
740
        bool operator<(const Iterator &it) const { return position() < it.position(); }
741
742
        Fragment *operator*() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
743
        const Fragment *operator*() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
744
        Fragment *operator->() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
745
        const Fragment *operator->() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
746
747
        int position() const { Q_ASSERT(!atEnd()); return pt->data.position(n); }
748
        const Fragment *value() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
749
        Fragment *value() { Q_ASSERT(!atEnd()); return pt->fragment(n); }
750
751
        Iterator& operator++() {
752
            n = pt->data.next(n);
753
            return *this;
754
        }
755
        Iterator& operator--() {
756
            n = pt->data.previous(n);
757
            return *this;
758
        }
759
760
    };
761
762
763
    class ConstIterator
764
    {
765
    public:
766
        const QFragmentMap *pt;
767
        quint32 n;
768
769
        /**
770
         * Functions
771
         */
772
        ConstIterator() : pt(0), n(0) {}
773
        ConstIterator(const QFragmentMap *p, int node) : pt(p), n(node) {}
774
        ConstIterator(const ConstIterator& it) : pt(it.pt), n(it.n) {}
775
        ConstIterator(const Iterator& it) : pt(it.pt), n(it.n) {}
776
777
        inline bool atEnd() const { return !n; }
778
779
        bool operator==(const ConstIterator& it) const { return pt == it.pt && n == it.n; }
780
        bool operator!=(const ConstIterator& it) const { return pt != it.pt || n != it.n; }
781
        bool operator<(const ConstIterator &it) const { return position() < it.position(); }
782
783
        const Fragment *operator*()  const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
784
        const Fragment *operator->()  const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
785
786
        int position() const { Q_ASSERT(!atEnd()); return pt->data.position(n); }
787
        int size() const { Q_ASSERT(!atEnd()); return pt->data.size(n); }
788
        const Fragment *value() const { Q_ASSERT(!atEnd()); return pt->fragment(n); }
789
790
        ConstIterator& operator++() {
791
            n = pt->data.next(n);
792
            return *this;
793
        }
794
        ConstIterator& operator--() {
795
            n = pt->data.previous(n);
796
            return *this;
797
        }
798
    };
799
800
801
    QFragmentMap() {}
802
    ~QFragmentMap()
803
    {
804
        if (!data.fragments)
805
            return; // in case of out-of-memory, we won't have fragments
806
        for (Iterator it = begin(); !it.atEnd(); ++it)
807
            it.value()->free();
808
    }
809
810
    inline void clear() {
811
        for (Iterator it = begin(); !it.atEnd(); ++it)
812
            it.value()->free();
813
        data.init();
814
    }
815
816
    inline Iterator begin() { return Iterator(this, data.minimum(data.root())); }
817
    inline Iterator end() { return Iterator(this, 0); }
818
    inline ConstIterator begin() const { return ConstIterator(this, data.minimum(data.root())); }
819
    inline ConstIterator end() const { return ConstIterator(this, 0); }
820
821
    inline ConstIterator last() const { return ConstIterator(this, data.maximum(data.root())); }
822
823
    inline bool isEmpty() const { return data.head->node_count == 0; }
824
    inline int numNodes() const { return data.head->node_count; }
825
    int length(uint field = 0) const { return data.length(field); }
826
827
    Iterator find(int k, uint field = 0) { return Iterator(this, data.findNode(k, field)); }
828
    ConstIterator find(int k, uint field = 0) const { return ConstIterator(this, data.findNode(k, field)); }
829
830
    uint findNode(int k, uint field = 0) const { return data.findNode(k, field); }
831
832
    uint insert_single(int key, uint length)
833
    {
834
        uint f = data.insert_single(key, length);
835
        if (f != 0) {
836
            Fragment *frag = fragment(f);
837
            Q_ASSERT(frag);
838
            frag->initialize();
839
        }
840
        return f;
841
    }
842
    uint erase_single(uint f)
843
    {
844
      if (f != 0) {
845
          Fragment *frag = fragment(f);
846
          Q_ASSERT(frag);
847
          frag->free();
848
      }
849
      return data.erase_single(f);
850
    }
851
852
    inline Fragment *fragment(uint index) {
853
        Q_ASSERT(index != 0);
854
        return data.fragment(index);
855
    }
856
    inline const Fragment *fragment(uint index) const {
857
        Q_ASSERT(index != 0);
858
        return data.fragment(index);
859
    }
860
    inline uint position(uint node, uint field = 0) const { return data.position(node, field); }
861
    inline bool isValid(uint n) const { return data.isValid(n); }
862
    inline uint next(uint n) const { return data.next(n); }
863
    inline uint previous(uint n) const { return data.previous(n); }
864
    inline uint size(uint node, uint field = 0) const { return data.size(node, field); }
865
    inline void setSize(uint node, int new_size, uint field = 0)
866
        { data.setSize(node, new_size, field);
867
      if (node != 0 && field == 0) {
868
          Fragment *frag = fragment(node);
869
          Q_ASSERT(frag);
870
          frag->invalidate();
871
      }
872
    }
873
874
    inline int firstNode() const { return data.minimum(data.root()); }
875
876
private:
877
    friend class Iterator;
878
    friend class ConstIterator;
879
880
    QFragmentMapData<Fragment> data;
881
882
    QFragmentMap(const QFragmentMap& m);
883
    QFragmentMap& operator= (const QFragmentMap& m);
884
};
885
886
QT_END_NAMESPACE
887
888
#endif // QFRAGMENTMAP_P_H