Boost logo

Boost Users :

Subject: [Boost-users] Help for using interprocess::managed_mapped_file
From: Kanthimathi Kalyanamandapam (kkmadrasi_at_[hidden])
Date: 2010-04-01 13:07:58


Hi: I am experimenting with managed_mapped_file to store a vector of a complex_data encapsulating a string and an array quite like the provided "containers of containers" example. However, the program behaves in a rather erratic manner , throwing up boost::interprocess_exception::library_error quite randomly after inserting a few elements. I am including the program below , any help on this will be highly appreciated, With Regards, Kanthi K ///////////////////////// // Compile with: g++ -ansi -Wall -O2 -lrt -o output progname.cc #include <iostream> #include <string> #include <map> #include <list> #include <boost/tuple/tuple.hpp> #include <boost/interprocess/managed_mapped_file.hpp> #include <boost/interprocess/allocators/allocator.hpp> #include <boost/interprocess/containers/string.hpp> #include <boost/interprocess/containers/vector.hpp> #include <boost/interprocess/exceptions.hpp> #define MEGABYTE 1048576L /** * Class for storing data in a mmap file */ class memmapfile { private: typedef boost::interprocess::managed_mapped_file managed_mapped_file_t; typedef managed_mapped_file_t::segment_manager segment_manager_t; typedef boost::interprocess::allocator<void, segment_manager_t> void_alloc; typedef boost::interprocess::allocator<int, segment_manager_t> int_alloc; typedef boost::interprocess::allocator<char, segment_manager_t> char_alloc; typedef boost::interprocess::vector<int, int_alloc> mm_int_vector; typedef boost::interprocess::basic_string<char, std::char_traits<char>, char_alloc> mm_string; typedef std::list<int> std_int_list; /* holder */ struct holder { holder(mm_string mstr, mm_int_vector mintvec) : mstr_(boost::interprocess::move(mstr)), mintvec_(boost::interprocess::move(mintvec)) { } ~holder() {} private: mm_string mstr_; mm_int_vector mintvec_; }; typedef boost::interprocess::allocator<holder, segment_manager_t> holder_alloc; typedef boost::interprocess::vector<holder, holder_alloc> mm_holder_vector; /** functions */ /** segment functions */ void open_file() { segment = managed_mapped_file_t(boost::interprocess::open_or_create, file_location_.c_str(), file_size_); void_alloc alloc_inst(segment.get_segment_manager()); mm_holder_vector *usevec; usevec = segment.find_or_construct<mm_holder_vector> (boost::interprocess::unique_instance) (alloc_inst); std::cerr << "Vec Size at open : " << usevec->size() << std::endl; } void grow_file(std::size_t ExtraBytes) { if (ExtraBytes <= 0) ExtraBytes=file_incr_unit; std::cerr << "Growing file : " << file_size_ << " + " << ExtraBytes << " = "; segment.grow(file_location_.c_str(),ExtraBytes); segment = managed_mapped_file_t(boost::interprocess::open_only, file_location_.c_str()); file_size_ = segment.get_size(); std::cerr << file_size_ << std::endl; } void init_usevec(bool clear) { void_alloc alloc_inst(segment.get_segment_manager()); mm_holder_vector *usevec; std::size_t count=0; boost::tie(usevec,count) = segment.find<mm_holder_vector> (boost::interprocess::unique_instance); if (count==0) { std::cerr << "Cannot find vector" << std::endl; exit(1); } if (clear) { std::cerr << "Clearing vector" << std::endl; segment.destroy<mm_holder_vector>(boost::interprocess::unique_instance); usevec = segment.construct<mm_holder_vector> (boost::interprocess::unique_instance) (alloc_inst); } } /* variables */ std::string file_location_; std::size_t file_size_; const std::size_t file_incr_unit; managed_mapped_file_t segment; public: memmapfile(const std::string file_location, const std::size_t file_size, bool clear) : file_location_(file_location), file_size_(file_size), file_incr_unit(file_size) { try { open_file(); if (file_size_ > segment.get_size()) grow_file(file_size_ - segment.get_size()); init_usevec(clear); } catch (...) { std::cerr << " Cannot init mmapfile " << std::endl; exit(1); } } virtual ~memmapfile() {} /** * add: add an entry */ template<class T> std::size_t add(const std::string& in_str, const T& in_list) { std::size_t ret=0; try { std::size_t min_space_need = (in_str.length() * sizeof(char)) + (in_list.size() * sizeof(typename T::value_type)); while ( min_space_need*4 > segment.get_free_memory() ) { grow_file(file_incr_unit); } void_alloc alloc_inst(segment.get_segment_manager()); mm_holder_vector *usevec; std::size_t count=0; boost::tie(usevec,count) = segment.find<mm_holder_vector> (boost::interprocess::unique_instance); if (count==0) { std::cerr << "Cannot find vector" << std::endl; exit(1); } mm_string move_mstr(alloc_inst); mm_int_vector move_mintvec(alloc_inst); move_mstr = in_str.c_str(); for (typename T::const_iterator it = in_list.begin() ; it!= in_list.end() ; ++it) { move_mintvec.push_back(*it); } usevec->push_back(holder(move_mstr,move_mintvec)); ret = usevec->size(); std::cerr << "Added, Vec size: " << usevec->size() << "/" << usevec->max_size() << ", "; std::cerr << "Memory free: " << segment.get_free_memory() << "/" << segment.get_size() << ", "; double f = ((double)segment.get_free_memory()/(double)segment.get_size()) * 100; std::cerr << "% : " << f << std::endl; } catch (boost::interprocess::interprocess_exception e) { std::cerr << "Cannot add: " << e.what() << std::endl; exit(1); } return ret; } }; int main() { typedef std::list<int> std_int_list; std::string in_str = "abcdefghijklmnopqrstuvwxyz"; std_int_list in_list; for (int i=0; i<1024*8; ++i) { in_list.push_back(i) ; } std::size_t min_space_need = (in_str.length() * sizeof(char)) + (in_list.size() * sizeof(std_int_list::value_type)); std::cerr << "#### min space needed: " << min_space_need << std::endl; memmapfile* m = new memmapfile("test.bin",MEGABYTE,false); int i=0; while (++i<100) { std::size_t sz = m->add<std_int_list>(in_str,in_list); std::cerr << "Added in main loop: " << sz << std::endl; } } Your Mail works best with the New Yahoo Optimized IE8. Get it NOW! http://downloads.yahoo.com/in/internetexplorer/


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net