#include #include #include #include #include #include using namespace boost::interprocess; // I'm lazy to invent The Proper Type for Routes Dictionary Keys // timeval + pid would perfectly work and cheap to implement struct RouteKey: timeval { protected: bool init(const char* _id) { return (3 == sscanf(_id, "%lX.%lX.%X", &this->tv_sec, &this->tv_usec, &this->pid)); } public: pid_t pid; bool operator==(const RouteKey& _o) const { return (this->tv_sec == _o.tv_sec && this->tv_usec == _o.tv_usec && this->pid == _o.pid ); } bool operator<(const RouteKey& _o) const { return (this->tv_sec < _o.tv_sec || this->tv_usec < _o.tv_usec || this->pid < _o.pid ); } RouteKey(const char* _id) { if (!init(_id)) { throw std::invalid_argument("Invalid Route Key format"); } } // no-throw variant of the construct-from-id RouteKey(bool& _success, const char* _id) throw () { _success = init(_id); } operator const std::string() const { char buf[40 + 1 + 40 + 1 + 40 + 1]; sprintf(buf, "%lX.%lX.%X", this->tv_sec, this->tv_usec, this->pid); return std::string(buf); } }; #define ROUTE_SEGMENT_NAME "TestSegment" #define ROUTE_MAP_NAME "TestRoutes" #define ROUTE_SEGMENT_SIZE 1024 * 1024 * 20 typedef std::pair RouteMapValue; typedef allocator RouteMapValueAllocator; typedef map, RouteMapValueAllocator> RouteMap; void addItem(const char* _k) { managed_shared_memory segment(open_only, ROUTE_SEGMENT_NAME); RouteMapValueAllocator alloc(segment.get_segment_manager()); RouteMap *mymap = segment.find(ROUTE_MAP_NAME).first; RouteKey k(_k); RouteMapValue v(k, 1); mymap->insert(v); } int findItem(const char* _k) { managed_shared_memory segment(open_only, ROUTE_SEGMENT_NAME); RouteMapValueAllocator alloc(segment.get_segment_manager()); RouteMap *mymap = segment.find(ROUTE_MAP_NAME).first; RouteKey k(_k); RouteMap::const_iterator it = mymap->find(k); if (it == mymap->end()) { printf("element %s is NOT found\n", ((const std::string&)k).c_str()); return 55; } printf("element %s is in the map\n", ((const std::string&)k).c_str()); return 0; } void listItems() { managed_shared_memory segment(open_only, ROUTE_SEGMENT_NAME); RouteMapValueAllocator alloc(segment.get_segment_manager()); RouteMap *mymap = segment.find(ROUTE_MAP_NAME).first; printf("RouteMap content (%zd element(s)):\n", mymap->size()); for(RouteMap::const_iterator it = mymap->begin(); it != mymap->end(); ++it) { printf(" \"%s\"\n", ((const std::string&)it->first).c_str()); } printf("end of RouteMap content\n"); } void createSegment() { managed_shared_memory segment(open_or_create, ROUTE_SEGMENT_NAME, ROUTE_SEGMENT_SIZE); RouteMapValueAllocator alloc(segment.get_segment_manager()); RouteMap *mymap = segment.find_or_construct(ROUTE_MAP_NAME) //object name (std::less() //first ctor parameter ,alloc); //second ctor parameter } int main(int argc, char* argv[]) { if (argc < 2) { fprintf(stderr, "Invalid usage\n"); return 2; } if (0 == strcmp("create", argv[1])) { createSegment(); return 0; } else if (0 == strcmp("add", argv[1])) { if (argc < 3) { fprintf(stderr, "insufficient parameters for add\n"); return 3; } addItem(argv[2]); return 0; } else if (0 == strcmp("find", argv[1])) { if (argc < 3) { fprintf(stderr, "insufficient parameters for find\n"); return 4; } return findItem(argv[2]); } if (0 == strcmp("list", argv[1])) { listItems(); return 0; } else { fprintf(stderr, "unknown command\n"); return 5; } }