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
#include
#include
#include
#include
#include
#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_alloc;
typedef boost::interprocess::allocator int_alloc;
typedef boost::interprocess::allocator char_alloc;
typedef boost::interprocess::vector mm_int_vector;
typedef boost::interprocess::basic_string 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_alloc;
typedef boost::interprocess::vector 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 (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 (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(boost::interprocess::unique_instance);
usevec = segment.construct (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 (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(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/