#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_DEBUG(_X_, _Y_) std::cout << _Y_ << std::endl struct BalanceNode : #if USE_OFFSET_PTR == 0 #warning without offet_ptr public bin::avl_set_base_hook > #else #warning with offet_ptr public bin::avl_set_base_hook< bin::optimize_size, bin::void_pointer< bip::offset_ptr > > #endif { int int_; friend bool operator< (const BalanceNode &a, const BalanceNode &b) { return a.int_ < b.int_; } friend bool operator> (const BalanceNode &a, const BalanceNode &b) { return a.int_ > b.int_; } friend bool operator== (const BalanceNode &a, const BalanceNode &b) { return a.int_ < b.int_; } }; // Define an avl_set using the base hook typedef bin::avl_set< BalanceNode > BalanceSet; // typedef bin::avl_set< BalanceNode, bin::void_pointer< bip::offset_ptr > > BalanceSet; struct Header { uint8_t m_magic[4]; uint8_t m_reserved1[4]; uint8_t m_fileVersionMajor; uint8_t m_fileVersionMinor; uint8_t m_headerSize; uint8_t m_balanceNodeSize; uint8_t m_balanceSetSize; uint8_t m_decimalSize; uint8_t m_bits; uint8_t m_bigEndian; uint64_t m_count; uint64_t m_avail; uint64_t m_offset; uint64_t m_reserved2; Header(size_t avail, size_t offset) : m_fileVersionMajor(1), m_fileVersionMinor(0), m_headerSize(sizeof(Header)), m_balanceNodeSize(sizeof(BalanceNode)), m_balanceSetSize(sizeof(BalanceSet)), m_decimalSize(0), m_bits(sizeof(void *) * 8), #ifdef ACE_LITTLE_ENDIAN m_bigEndian(0), #else m_bigEndian(1), #endif m_count(0), m_avail(avail), m_offset(offset) { ::memcpy( reinterpret_cast(&m_magic), reinterpret_cast("TSBI"), sizeof(uint32_t) ); ::memset( reinterpret_cast(&m_reserved1), 0, sizeof(m_reserved1) ); ::memset( reinterpret_cast(&m_reserved2), 0, sizeof(m_reserved2) ); } }; int main (int, char **) { LOG4CPLUS_DEBUG(s_logger, "sizeof(BalanceNode)=" << sizeof(BalanceNode)); LOG4CPLUS_DEBUG(s_logger, "sizeof(BalanceSet)=" << sizeof(BalanceSet)); std::filebuf fbuf; fbuf.open( "/tmp/avltest.img", std::ios_base::in ); if(!fbuf.is_open()) { LOG4CPLUS_DEBUG(s_logger, "creating file ..."); fbuf.close(); fbuf.open( "/tmp/avltest.img", std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary ); //Set the size fbuf.pubseekoff(0x250, std::ios_base::beg); fbuf.sputc(0); LOG4CPLUS_DEBUG(s_logger, "creating file done"); } fbuf.close(); bip::file_mapping file( "/tmp/avltest.img", //filename bip::read_write //read-write mode ); bip::mapped_region header( file, //Memory-mappable object bip::read_write, //Access mode 0, //Offset from the beginning of shm 0x80 //Length of the region ); LOG4CPLUS_DEBUG(s_logger, "header.get_address()=" << header.get_address()); LOG4CPLUS_DEBUG(s_logger, "header.get_size()=" << header.get_size()); Header * p_header = reinterpret_cast
(header.get_address()); size_t avail = 5; size_t size = (avail + 1) * sizeof(BalanceNode) + sizeof(BalanceSet); bip::mapped_region region ( file, //Memory-mappable object bip::read_write, //Access mode 0x80, //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(region.get_address()); LOG4CPLUS_DEBUG(s_logger, "p_values (before)=" << p_values); if(p_header->m_offset == 0) { ::memset( header.get_address(), 0xFF, 0x80 ); size_t offset = 0; do { ++p_values; offset = reinterpret_cast(p_values) - reinterpret_cast(p_set); }while(offset <= sizeof(BalanceSet)); LOG4CPLUS_DEBUG(s_logger, "offset=" << offset); ::memset( region.get_address(), 0xFF, offset ); LOG4CPLUS_DEBUG(s_logger, "initializing header ..."); p_header = new (header.get_address()) Header(avail, offset); LOG4CPLUS_DEBUG(s_logger, "initializing header done"); LOG4CPLUS_DEBUG(s_logger, "p_header->m_avail=" << p_header->m_avail); LOG4CPLUS_DEBUG(s_logger, "p_header->m_count=" << p_header->m_count); LOG4CPLUS_DEBUG(s_logger, "initializing set ..."); p_set = new (region.get_address()) BalanceSet(); LOG4CPLUS_DEBUG(s_logger, "initializing set done"); region.flush(); } else { LOG4CPLUS_DEBUG(s_logger, "m_offset=" << p_header->m_offset); p_values = reinterpret_cast( reinterpret_cast(region.get_address()) + p_header->m_offset ); LOG4CPLUS_DEBUG(s_logger, "found " << p_header->m_count << " entries"); } LOG4CPLUS_DEBUG(s_logger, "p_values (after) =" << p_values); if(p_header->m_count == 0) { //Now insert them in the sets for(size_t idx = 0; idx < p_header->m_avail; ++idx) { LOG4CPLUS_DEBUG(s_logger, "creating entry " << idx << " ..."); ++p_header->m_count; p_values[idx].int_ = ('T' + idx); LOG4CPLUS_DEBUG(s_logger, "creating entry " << idx << " done"); LOG4CPLUS_DEBUG(s_logger, "int=" << p_values[idx].int_); LOG4CPLUS_DEBUG(s_logger, "inserting entry " << idx << " ..."); p_set->insert(p_values[idx]); LOG4CPLUS_DEBUG(s_logger, "inserting entry " << idx << " done"); } LOG4CPLUS_DEBUG(s_logger, "created/inserted " << p_header->m_count << " entries"); region.flush(); } for(size_t idx = 0; idx < p_header->m_count; ++idx) { LOG4CPLUS_DEBUG(s_logger, "int=" << p_values[idx].int_); } for(BalanceSet::iterator it(p_set->begin()), end(p_set->end()); it != end; ++it) { LOG4CPLUS_DEBUG(s_logger, "int=" << it->int_); } }