// linux compile line: // g++ -O2 -o josh-shared-data josh-shared-data.cpp -lpthread -lrt #include #include #include #include #include #include #include #include #include namespace bi = boost::interprocess; class TestStore { public: struct Datum { uint16_t commandStatus; std::size_t wordCount; uint16_t data[32]; Datum( uint16_t commandStatus, std::size_t wordCount ) : commandStatus( commandStatus ), wordCount( wordCount ) { for ( std::size_t i = 0; i < 32; ++i ) data[i] = 0; } friend std::ostream & operator << ( std::ostream & os, const Datum & data ) { os << "[Datum: cs=" << data.commandStatus << ", wc=" << data.wordCount << ", data=<" << data.data[0]; for ( std::size_t i = 1; i < 32; ++i ) os << " " << data.data[i]; os << ">]"; return os; } }; enum ReplaceFlag { REPLACE_EXISTING, KEEP_EXISTING }; TestStore( const std::string & segName, const std::string & mapName, const ReplaceFlag replace = KEEP_EXISTING, const std::size_t segSize = 600U*1024U ) : mReplacer( segName, replace ), mSegment( bi::open_or_create, segName.c_str(), segSize ), mData( mSegment.find_or_construct< Map >( mapName.c_str() )( std::less< Key >(), mSegment.get_allocator< MapValueType >() ) ) { } void printData() { using std::clog; using std::endl; BOOST_FOREACH( const Map::value_type & outer, *mData ) { clog << "key: " << outer.first << endl; BOOST_FOREACH( const List::value_type & inner, outer.second ) clog << " " << inner << endl; } } bool addMessage( unsigned key, const Datum & datum ) { Map::iterator it( mData->find(key) ); if ( it == mData->end() ) { ListAllocator alloc( mSegment.get_segment_manager() ); std::pair< Map::iterator, bool > rv( mData->insert( Map::value_type( key, List( alloc ) ) ) ); it = rv.first; } it->second.push_back( datum ); return true; } private: typedef bi::managed_shared_memory Segment; typedef Segment::segment_manager Manager; typedef bi::allocator< Datum, Manager > ListAllocator; typedef bi::list< Datum, ListAllocator > List; typedef unsigned int Key; typedef std::pair< const Key, List > MapValueType; typedef bi::allocator< MapValueType, Manager > MapAllocator; typedef bi::map< Key, List, std::less< Key >, MapAllocator> Map; struct Replacer { Replacer( const std::string segName, const ReplaceFlag action ) { if ( action == REPLACE_EXISTING ) bi::shared_memory_object::remove( segName.c_str() ); } }; Replacer mReplacer; Segment mSegment; Map * mData; }; int main() { const std::string segName = "JoshSharedSeg"; const std::string mapName = "map"; TestStore store( segName, mapName, TestStore::REPLACE_EXISTING ); using std::clog; using std::endl; clog << "before:" << endl; store.printData(); TestStore::Datum datum( 10, 14 ); store.addMessage( 3, datum ); clog << "after:" << endl; store.printData(); return 0; }