File: test_hash_map_reader_writer.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 (176 lines) | stat: -rw-r--r-- 6,215 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
/***************************************************************************
 *  tests/containers/hash_map/test_hash_map_reader_writer.cpp
 *
 *  Part of the STXXL. See http://stxxl.sourceforge.net
 *
 *  Copyright (C) 2007 Markus Westphal <marwes@users.sourceforge.net>
 *
 *  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 <iostream>

#include <stxxl.h>
#include <stxxl/bits/common/seed.h>
#include <stxxl/bits/containers/hash_map/util.h>

void reader_writer_test()
{
    typedef std::pair<unsigned, unsigned> value_type;

    const unsigned subblock_raw_size = 1024 * 8; // 8KB subblocks
    const unsigned block_size = 128;             // 1MB blocks (=128 subblocks)

    const unsigned n_blocks = 64;                // number of blocks to use for this test
    const unsigned cache_size = 8;               // size of cache in blocks

    const unsigned buffer_size = 4;              // write buffer size in blocks

    typedef stxxl::typed_block<subblock_raw_size, value_type> subblock_type;
    typedef stxxl::typed_block<block_size* sizeof(subblock_type), subblock_type> block_type;

    const unsigned subblock_size = subblock_type::size;  // size in values

    typedef block_type::bid_type bid_type;
    typedef std::vector<bid_type> bid_container_type;
    typedef bid_container_type::iterator bid_iterator_type;

    typedef stxxl::hash_map::block_cache<block_type> cache_type;

    typedef stxxl::hash_map::buffered_writer<block_type, bid_container_type> writer_type;
    typedef stxxl::hash_map::buffered_reader<cache_type, bid_iterator_type> reader_type;

    bid_container_type bids;
    cache_type cache(cache_size);

    // plain writing
    {
        writer_type writer(&bids, buffer_size, buffer_size / 2);
        unsigned i = 0;
        for ( ; i < n_blocks * block_size * subblock_size; ++i)
            writer.append(value_type(i, i));
        writer.flush();

        STXXL_CHECK(bids.size() >= n_blocks);

        block_type* block = new block_type;
        i = 0;
        for (unsigned i_block = 0; i_block < n_blocks; i_block++) {
            stxxl::request_ptr req = block->read(bids[i_block]);
            req->wait();

            for (unsigned inner = 0; inner < block_size * subblock_size; ++inner) {
                STXXL_CHECK((*block)[inner / subblock_size][inner % subblock_size].first == i);
                i++;
            }
        }
        delete block;
    }

    // reading with/without prefetching
    {
        // last parameter disables prefetching
        reader_type reader(bids.begin(), bids.end(), cache, 0, false);
        for (unsigned i = 0; i < n_blocks * block_size * subblock_size; ++i) {
            STXXL_CHECK(reader.const_value().first == i);
            ++reader;
        }

        // prefetching enabled by default
        reader_type reader2(bids.begin(), bids.end(), cache);
        for (unsigned i = 0; i < n_blocks * block_size * subblock_size; ++i) {
            STXXL_CHECK(reader2.const_value().first == i);
            ++reader2;
        }
    }

    // reading with skipping
    {
        // disable prefetching
        reader_type reader(bids.begin(), bids.end(), cache, 0, false);

        // I: first subblock
        reader.skip_to(bids.begin() + 10, 0);
        unsigned expected = block_size * subblock_size * 10 + subblock_size * 0;
        STXXL_CHECK(reader.const_value().first == expected);

        // II: subblock in the middle (same block)
        reader.skip_to(bids.begin() + 10, 2);
        expected = block_size * subblock_size * 10 + subblock_size * 2;
        STXXL_CHECK(reader.const_value().first == expected);

        // III: subblock in the middle (another block)
        reader.skip_to(bids.begin() + 13, 1);
        expected = block_size * subblock_size * 13 + subblock_size * 1;
        STXXL_CHECK(reader.const_value().first == expected);
    }

    // reading with modifying access
    {
        reader_type reader(bids.begin(), bids.end(), cache);
        for (unsigned i = 0; i < n_blocks * block_size * subblock_size; ++i) {
            reader.value().second = reader.const_value().first + 1;
            ++reader;
        }

        reader_type reader2(bids.begin(), bids.end(), cache);
        for (unsigned i = 0; i < n_blocks * block_size * subblock_size; ++i) {
            STXXL_CHECK(reader2.const_value().second == reader2.const_value().first + 1);
            ++reader2;
        }

        cache.flush();
        block_type* block = new block_type;
        unsigned i = 0;
        for (unsigned i_block = 0; i_block < n_blocks; i_block++) {
            stxxl::request_ptr req = block->read(bids[i_block]);
            req->wait();

            for (unsigned inner = 0; inner < block_size * subblock_size; ++inner) {
                STXXL_CHECK((*block)[inner / subblock_size][inner % subblock_size].first == i);
                STXXL_CHECK((*block)[inner / subblock_size][inner % subblock_size].second == i + 1);
                i++;
            }
        }
        delete block;
    }

    //cache.dump_cache();

    cache.clear();

    // finishinging subblocks: skip second half of each subblock
    {
        writer_type writer(&bids, buffer_size, buffer_size / 2);
        unsigned i = 0;
        for (unsigned outer = 0; outer < n_blocks * block_size; ++outer) {
            for (unsigned inner = 0; inner < subblock_size / 2; ++inner) {
                writer.append(value_type(i, i));
                ++i;
            }
            writer.finish_subblock();
        }
        writer.flush();

        reader_type reader(bids.begin(), bids.end(), cache);
        i = 0;
        for (unsigned outer = 0; outer < n_blocks * block_size; ++outer) {
            for (unsigned inner = 0; inner < subblock_size / 2; ++inner) {
                STXXL_CHECK(reader.const_value().first == i);
                ++i;
                ++reader;
            }
            reader.next_subblock();
        }
    }

    STXXL_MSG("Passed Reader-Writer Test");
}

int main()
{
    reader_writer_test();
    return 0;
}