int main() { // Create a vector with 3 default Test objects (-1) and reserved space for 6 objects. // Content afterwards: {-1,-1,-1} stxxl::swap_vector<Test> vec(3, 6); // Push back 10 values from 0 to 9. Internally a swap resize will happen // Content afterwards: {-1,-1,-1,0,1,2,3,4,5,6,7,8,9} for (unsigned i = 0; i < 10; ++i) { Test a(i); vec.swap_back(a); } // Delete the third and the fourth object. // Content afterwards: {-1,-1,1,2,3,4,5,6,7,8,9} vec.erase(vec.begin() + 2, vec.begin() + 4); // Delete the sixth object. // Content afterwards: {-1,-1,1,2,3,5,6,7,8,9} vec.erase(vec.begin() + 5); // Check the values. int expected_vals[10] = { -1, -1, 1, 2, 3, 5, 6, 7, 8, 9 }; die_unequal(vec.size(), 10u); for (unsigned i = 0; i < vec.size(); ++i) { die_unequal(vec[i].get_i(), expected_vals[i]); } // std::remove_if would fail because it makes use of copy assignment. // We test stxxl's swap_remove_if implementation instead. // STL: vec.erase(std::remove_if(vec.begin(), vec.end(), test_eraser()), vec.end()); vec.erase(stxxl::swap_remove_if(vec.begin(), vec.end(), test_eraser()), vec.end()); // Check the values. int expected_vals2[10] = { 1, 2, 3, 5, 6, 7, 9 }; die_unequal(vec.size(), 7u); for (unsigned i = 0; i < vec.size(); ++i) { die_unequal(vec[i].get_i(), expected_vals2[i]); } // Clear the vector. vec.clear(); die_unless(vec.empty()); // Resize to 100 and overwrite the last value. // Content after resize and overwrite: {...,-1,100} // Note: clear() does not overwrite any values in the underlaying array. vec.resize(20); Test t(11); std::swap(vec[19], t); // Check the values. die_unequal(vec.size(), 20u); die_unequal(vec[19].get_i(), 11); return EXIT_SUCCESS; }
bool test_block_cache() { using value_type = std::pair<int, int>; constexpr size_t magic1 = 0xc01ddead; constexpr unsigned subblock_raw_size = 1024 * 8; // 8KB subblocks constexpr unsigned block_size = 128; // 1MB blocks (=128 subblocks) constexpr unsigned num_blocks = 64; // number of blocks to use for this test constexpr unsigned cache_size = 8; // size of cache in blocks using subblock_type = foxxll::typed_block<subblock_raw_size, value_type>; using block_type = foxxll::typed_block<block_size* sizeof(subblock_type), subblock_type>; constexpr unsigned subblock_size = subblock_type::size; // size in values using bid_type = block_type::bid_type; using bid_container_type = std::vector<bid_type>; // prepare test: allocate blocks, fill them with values and write to disk bid_container_type bids(num_blocks); foxxll::block_manager* bm = foxxll::block_manager::get_instance(); bm->new_blocks(foxxll::striping(), bids.begin(), bids.end()); block_type* block = new block_type; for (unsigned i_block = 0; i_block < num_blocks; i_block++) { for (unsigned i_subblock = 0; i_subblock < block_size; i_subblock++) { for (unsigned i_value = 0; i_value < subblock_size; i_value++) { int value = i_value + i_subblock * subblock_size + i_block * block_size; (*block)[i_subblock][i_value] = value_type(value, value); } } foxxll::request_ptr req = block->write(bids[i_block]); req->wait(); } std::mt19937 randgen; std::uniform_int_distribution<int> distr_num(0, num_blocks - 1); std::uniform_int_distribution<int> distr_size(0, block_size - 1); // create block_cache using cache_type = stxxl::hash_map::block_cache<block_type>; cache_type cache(cache_size); // load random subblocks and check for values int n_runs = cache_size * 10; for (int i_run = 0; i_run < n_runs; i_run++) { int i_block = distr_num(randgen); int i_subblock = distr_size(randgen); subblock_type* subblock = cache.get_subblock(bids[i_block], i_subblock); int expected = i_block * block_size + i_subblock * subblock_size + 1; die_unless((*subblock)[1].first == expected); } // do the same again but this time with prefetching for (int i_run = 0; i_run < n_runs; i_run++) { int i_block = distr_num(randgen); int i_subblock = distr_size(randgen); cache.prefetch_block(bids[i_block]); subblock_type* subblock = cache.get_subblock(bids[i_block], i_subblock); int expected = i_block * block_size + i_subblock * subblock_size + 1; die_unless((*subblock)[1].first == expected); } // load and modify some subblocks; flush cache and check values randgen.seed(magic1); for (int i_run = 0; i_run < n_runs; i_run++) { int i_block = distr_num(randgen); int i_subblock = distr_size(randgen); subblock_type* subblock = cache.get_subblock(bids[i_block], i_subblock); die_unless(cache.make_dirty(bids[i_block])); (*subblock)[1].first = (*subblock)[1].second + 42; } randgen.seed(magic1); for (int i_run = 0; i_run < n_runs; i_run++) { int i_block = distr_num(randgen); int i_subblock = distr_size(randgen); subblock_type* subblock = cache.get_subblock(bids[i_block], i_subblock); int expected = i_block * block_size + i_subblock * subblock_size + 1; die_unequal((*subblock)[1].first, expected + 42); } // test retaining cache.clear(); // not yet cached die_unless(cache.retain_block(bids[0]) == false); cache.prefetch_block(bids[0]); // cached, should be retained die_unless(cache.retain_block(bids[0]) == true); // release again die_unless(cache.release_block(bids[0]) == true); // retrain-count should be 0, release fails die_unless(cache.release_block(bids[0]) == false); // cache new block subblock_type* kicked_subblock = cache.get_subblock(bids[1], 0); // load other blocks, so that kicked_subblock, well, gets kicked for (unsigned i = 0; i < cache_size + 5; i++) { cache.prefetch_block(bids[i + 3]); } // load kicked subblock again, should be at a different location die_unless(cache.get_subblock(bids[1], 0) != kicked_subblock); subblock_type* retained_subblock = cache.get_subblock(bids[1], 0); // now retain subblock die_unless(cache.retain_block(bids[1]) == true); for (unsigned i = 0; i < cache_size + 5; i++) { cache.prefetch_block(bids[i + 3]); } // retained_subblock should not have been kicked die_unless(cache.get_subblock(bids[1], 0) == retained_subblock); cache.clear(); // test swapping subblock_type* a_subblock = cache.get_subblock(bids[6], 1); cache_type cache2(cache_size / 2); std::swap(cache, cache2); die_unless(cache.size() == cache_size / 2); die_unless(cache2.size() == cache_size); die_unless(cache2.get_subblock(bids[6], 1) == a_subblock); delete block; LOG1 << "Passed Block-Cache Test"; return true; }
void Connection::SyncRecv(void* out_data, size_t size) { net::Buffer msg = RecvNext(); die_unequal(msg.size(), size); char* out_cdata = reinterpret_cast<char*>(out_data); std::copy(msg.begin(), msg.end(), out_cdata); }