#pragma once #include #include #include #include #include #include namespace rng { template inline void shuffle(R& rng, span span) { if(!span.size()) return; std::cout << " -> shuffling " << span.size() << " objects..." << std::flush; for(std::size_t i=span.size()-1;i>0;i--) { auto j = rng.next_long(i); std::swap(span[i], span[j]); } std::cout << " OK" << std::endl; } namespace { extern "C" int _can_allocate(std::size_t bytes); template inline bool can_allocate(std::size_t len) { return !!_can_allocate(len*sizeof(T)); } } template inline void unshuffle(R& rng, span span) { if(!span.size()) return; #define DYN 2 #define MAP 3 #if defined(_FS_SPILL_BUFFER) && (_FS_SPILL_BUFFER == DYN) D_dprintf("spill=dyn"); dynamic_spill_vector rng_values = //can_allocate(span.size()) //Is there any way we can not waste this malloc() when it's valid? span.size() <= FSV_DEFAULT_SPILL_AT ? dynamic_spill_vector (span.size(), FSV_DEFAULT_SPILL_AT) : dynamic_spill_vector (FSV_DEFAULT_SPILL_AT); #elif defined(_FS_SPILL_BUFFER) && (_FS_SPILL_BUFFER == MAP) D_dprintf("spill=map"); mapped_spill_vector rng_values = span.size() <= FSV_DEFAULT_SPILL_AT ? mapped_spill_vector (span.size(), FSV_DEFAULT_SPILL_AT) : mapped_spill_vector (FSV_DEFAULT_SPILL_AT, mapped_vector::from_temp(span.size() - FSV_DEFAULT_SPILL_AT)); #elif defined(_FS_SPILL_BUFFER) D_dprintf("spill=static"); fixed_spill_vector rng_values; #else D_dprintf("spill=none"); std::vector rng_values; rng_values.reserve(span.size()); #endif #undef MAP #undef DYN std::cout << " -> unshuffling " << span.size() << " objects..." << std::flush; for(std::size_t i=span.size()-1;i>0;i--) rng_values.push_back(rng.next_long(i)); for(std::size_t i=1;i