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;
}
|