#include "boost/operators.hpp" #include "boost/static_assert.hpp" #include "boost/intrusive/avl_set.hpp" #include "boost/interprocess/offset_ptr.hpp" #include "boost/interprocess/file_mapping.hpp" #include "boost/interprocess/mapped_region.hpp" #include #include namespace bin = boost::intrusive; namespace bip = boost::interprocess; #define LOG4CPLUS_TRACE(_X_, _Y_) #define LOG4CPLUS_DEBUG(_X_, _Y_) std::cout << _Y_ << std::endl struct BalanceNode : #if USE_OPTIMIZATION == 0 #warning without optimization public bin::avl_set_base_hook< bin::optimize_size, bin::void_pointer< bip::offset_ptr > > #else #warning with optimization public bin::avl_set_base_hook< bin::optimize_size, bin::void_pointer< bip::offset_ptr > > #endif { BalanceNode( int value ) : m_value(value) { } friend bool operator< (const BalanceNode &a, const BalanceNode &b) { return a.m_value < b.m_value; } friend bool operator> (const BalanceNode &a, const BalanceNode &b) { return a.m_value > b.m_value; } friend bool operator== (const BalanceNode &a, const BalanceNode &b) { return a.m_value < b.m_value; } int m_value; }; // Define an avl_set using the base hook typedef bin::avl_set< BalanceNode, bin::void_pointer< bip::offset_ptr > > BalanceSet; void create(char const * filename, std::size_t size, std::size_t numentries) { std::filebuf fbuf; fbuf.open( filename, std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary ); //Set the size fbuf.pubseekoff(size, std::ios_base::beg); fbuf.sputc(0); fbuf.close(); LOG4CPLUS_DEBUG(s_logger, "creating file " << filename << " done"); bip::file_mapping file( filename, //filename bip::read_write //read-write mode ); bip::mapped_region region( file, //Memory-mappable object bip::read_write, //Access mode 0, //Offset from the beginning of shm size //Length of the region ); LOG4CPLUS_DEBUG(s_logger, "region.get_address()=" << region.get_address()); LOG4CPLUS_DEBUG(s_logger, "region.get_size()=" << region.get_size()); BalanceSet * p_set = new (region.get_address()) BalanceSet(); LOG4CPLUS_DEBUG(s_logger, "p_set=" << p_set); BalanceNode * p_values = reinterpret_cast( reinterpret_cast(region.get_address()) + sizeof(BalanceSet) + (sizeof(BalanceSet) % 16) ); LOG4CPLUS_DEBUG(s_logger, "p_values=" << p_values); //Now insert them in the set for(size_t idx = 0; idx < numentries; ++idx) { LOG4CPLUS_TRACE(s_logger, "creating entry " << idx << " ..."); new (&p_values[idx]) BalanceNode('T' + idx); LOG4CPLUS_TRACE(s_logger, "creating entry " << idx << " done"); LOG4CPLUS_TRACE(s_logger, "m_value=" << p_values[idx].m_value); LOG4CPLUS_TRACE(s_logger, "inserting entry " << idx << " ..."); p_set->find(p_values[idx]); p_set->insert(p_values[idx]); LOG4CPLUS_TRACE(s_logger, "inserting entry " << idx << " done"); } LOG4CPLUS_DEBUG(s_logger, "created/inserted " << numentries << " entries"); } void check(char const * filename, std::size_t size, std::size_t numentries) { bip::file_mapping file( filename, //filename bip::read_write //read-write mode ); bip::mapped_region region( file, //Memory-mappable object bip::read_write, //Access mode 0, //Offset from the beginning of shm size //Length of the region ); LOG4CPLUS_DEBUG(s_logger, "region.get_address()=" << region.get_address()); LOG4CPLUS_DEBUG(s_logger, "region.get_size()=" << region.get_size()); BalanceSet * p_set = reinterpret_cast(region.get_address()); LOG4CPLUS_DEBUG(s_logger, "p_set=" << p_set); BalanceNode * p_values = reinterpret_cast( reinterpret_cast(region.get_address()) + sizeof(BalanceSet) + (sizeof(BalanceSet) % 16) ); LOG4CPLUS_DEBUG(s_logger, "p_values=" << p_values); //Now find them in the set BalanceSet::iterator it; for(size_t idx = 0; idx < numentries; ++idx) { LOG4CPLUS_TRACE(s_logger, "finding entry " << idx << " ..."); it = p_set->find(p_values[idx]); LOG4CPLUS_TRACE(s_logger, "m_value=" << (*it).m_value); LOG4CPLUS_TRACE(s_logger, "finding entry " << idx << " done"); } LOG4CPLUS_DEBUG(s_logger, "checked " << numentries << " entries"); } int main (int argc, char ** argv) { LOG4CPLUS_DEBUG(s_logger, "sizeof(BalanceNode)=" << sizeof(BalanceNode)); LOG4CPLUS_DEBUG(s_logger, "sizeof(BalanceSet)=" << sizeof(BalanceSet)); std::size_t const numentries = 50000; std::size_t const size = numentries * sizeof(BalanceNode) + sizeof(BalanceSet) + 16; char const * filename = "/tmp/avltest.img"; if(argc > 1) filename = argv[1]; create(filename, size, numentries); check(filename, size, numentries); return 0; }