File: test_ext_merger2.cpp

package info (click to toggle)
libstxxl 1.4.1-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,476 kB
  • sloc: cpp: 45,101; ansic: 4,071; perl: 610; sh: 555; xml: 174; makefile: 18
file content (193 lines) | stat: -rw-r--r-- 6,202 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/***************************************************************************
 *  tests/containers/test_ext_merger2.cpp
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2008, 2009 Andreas Beckmann <beckmann@cs.uni-frankfurt.de>
 *
 *  Distributed under the Boost Software License, Version 1.0.
 *  (See accompanying file LICENSE_1_0.txt or copy at
 *  http://www.boost.org/LICENSE_1_0.txt)
 **************************************************************************/

#include <limits>
#include <iterator>
#include <stxxl/priority_queue>

typedef int my_type;
typedef stxxl::typed_block<4096, my_type> block_type;

struct dummy_merger
{
    int current, delta;
    dummy_merger() : current(0), delta(1) { }
    void operator () (int current_, int delta_)
    {
        current = current_;
        delta = delta_;
    }
    template <class OutputIterator>
    void multi_merge(OutputIterator b, OutputIterator e)
    {
        while (b != e)
        {
            * b = current;
            ++b;
            current += delta;
        }
    }
};

struct my_cmp : public std::greater<my_type>
{
    my_type min_value() const
    {
        return std::numeric_limits<my_type>::max();
    }
};

my_type * make_sequence(dummy_merger& dummy, int l)
{
    my_type* seq = new my_type[l + 1];  // + sentinel
    dummy.multi_merge(seq, seq + l);
    seq[l] = my_cmp().min_value();      // sentinel
    return seq;
}

// forced instantiation
const unsigned volume = 3 * 1024 * 1024; // in KiB
const unsigned mem_for_queue = 256 * 1024 * 1024;
template class stxxl::PRIORITY_QUEUE_GENERATOR<my_type, my_cmp, mem_for_queue, volume / sizeof(my_type)>;
template class stxxl::priority_queue_local::ext_merger<block_type, my_cmp, 5>;

int main()
{
    stxxl::config::get_instance();
    const int B = block_type::size;
    dummy_merger dummy;

    if (1) {
        const unsigned volume = 3 * 1024 * 1024; // in KiB
        const unsigned mem_for_queue = 256 * 1024 * 1024;
        typedef stxxl::PRIORITY_QUEUE_GENERATOR<my_type, my_cmp, mem_for_queue, volume / sizeof(my_type)>::result pq_type;
        pq_type pq(mem_for_queue, mem_for_queue);
        pq.push(42);
        STXXL_CHECK(pq.top() == 42);
        pq.pop();
        pq.push(2);
        pq.push(0);
        pq.push(3);
        pq.push(1);
        my_type x0, x1, x2, x3;
        x0 = pq.top();
        pq.pop();
        x1 = pq.top();
        pq.pop();
        x2 = pq.top();
        pq.pop();
        x3 = pq.top();
        pq.pop();
        STXXL_MSG("Order: " << x0 << " " << x1 << " " << x2 << " " << x3);
        STXXL_CHECK(x0 <= x1);
        STXXL_CHECK(x1 <= x2);
        STXXL_CHECK(x2 <= x3);
        STXXL_CHECK(pq.empty());
    }

    if (1) { // ext_merger test
        stxxl::read_write_pool<block_type> pool(1, 2);
        stxxl::priority_queue_local::ext_merger<block_type, my_cmp, 5> merger(&pool);
        dummy(1, 0);
        merger.insert_segment(dummy, B * 2);
        dummy(2, 0);
        merger.insert_segment(dummy, B * 2);
        dummy(B, 1);
        merger.insert_segment(dummy, B * 4);
        dummy(B, 2);
        merger.insert_segment(dummy, B * 4);
        dummy(B, 4);
        merger.insert_segment(dummy, B * 4);

        std::vector<my_type> output(B * 3);

        // zero length merge
        merger.multi_merge(output.begin(), output.begin());
        merger.multi_merge(output.begin(), output.begin());
        merger.multi_merge(output.begin(), output.begin());

        while (merger.size() > 0) {
            stxxl::unsigned_type l =
                std::min<stxxl::unsigned_type>(
                    (stxxl::unsigned_type)merger.size(), output.size()
                    );

            merger.multi_merge(output.begin(), output.begin() + l);
            STXXL_CHECK(stxxl::is_sorted(output.begin(), output.begin() + l));
            STXXL_MSG("merged " << l << " elements: (" << *output.begin() << ", ..., " << *(output.begin() + l - 1) << ")");
        }

        // zero length merge on empty data structure
        merger.multi_merge(output.begin(), output.begin());
        merger.multi_merge(output.begin(), output.begin());
        merger.multi_merge(output.begin(), output.begin());
    } // ext_merger test

    if (1) { // loser_tree test
        stxxl::priority_queue_local::loser_tree<my_type, my_cmp, 8> loser;
        dummy(1, 0);
        my_type* seq0 = make_sequence(dummy, 2 * B);
        dummy(2, 0);
        my_type* seq1 = make_sequence(dummy, 2 * B);
        dummy(B, 1);
        my_type* seq2 = make_sequence(dummy, 4 * B);
        dummy(B, 2);
        my_type* seq3 = make_sequence(dummy, 4 * B);
        dummy(2 * B, 1);
        my_type* seq4 = make_sequence(dummy, 4 * B);
        dummy(B, 4);
        my_type* seq5 = make_sequence(dummy, 4 * B);
        dummy(B, 8);
        my_type* seq6 = make_sequence(dummy, 4 * B);
        dummy(2 * B, 2);
        my_type* seq7 = make_sequence(dummy, 4 * B);

        loser.init();
        loser.insert_segment(seq0, 2 * B);
        loser.insert_segment(seq1, 2 * B);
        loser.insert_segment(seq2, 4 * B);
        loser.insert_segment(seq3, 4 * B);
        loser.insert_segment(seq4, 4 * B);
        if (0) {
            loser.insert_segment(seq5, 4 * B);
            loser.insert_segment(seq6, 4 * B);
            loser.insert_segment(seq7, 4 * B);
        } else {
            delete[] seq5;
            delete[] seq6;
            delete[] seq7;
        }

        my_type* out = new my_type[2 * B];

        // zero length merge
        loser.multi_merge(out, out);
        loser.multi_merge(out, out);
        loser.multi_merge(out, out);

        while (loser.size() > 0) {
            stxxl::uint64 l = std::min<stxxl::uint64>(loser.size(), B + B / 2 + 1);
            loser.multi_merge(out, out + l);
            STXXL_CHECK(stxxl::is_sorted(out, out + l));
            STXXL_MSG("merged " << l << " elements: (" << out[0] << ", ..., " << out[l - 1] << ")");
        }

        // zero length merge on empty data structure
        loser.multi_merge(out, out);
        loser.multi_merge(out, out);
        loser.multi_merge(out, out);

        delete[] out;
    } // loser_tree test
}

// vim: et:ts=4:sw=4