
Hi, ""JOAQUIN LOPEZ MU?Z"" wrotes
"vicente.botet" ha escrito:
Maybe this should be managed orthogonally but, can the current design manage with persistent flyweights? Which policies will we reused and which ones added?
Hi,
Here is a basic example of how to make a persistent factory (not to be confounded with serializaing flyweight objects, which is an entirely different matter). The factory below is based on a std::set and loads and saves its contents upon construction/destruction:
I don't know if I was looking exactly for a serializing flyweight. I'm sorry, I was not explicit at all. What I was looking for should behaves as follows: when a persistent flyweight is stored on a persistent storage it will look for a persistent shared object on the specific factory persistent storage. If a refcounted tracking policy is used will increase the reference counter. When we remove the flyweight from persistent storage this will decrease the reference counter if a refcounted tracking policy is used. If the counter is equal to 0 the shared object is removed from the specific factory persistent storage. We can think as we had two plans, one persistent and one transient (in memory). The objects shared in both plans do not have to match. I hope that this clarify what were my expectations with persistent flyweights. I think that this is out of the scope of the Flyweight library, so please do not take in account this point for the review. Best regards Vicente Botet
template<typename Entry,typename Value,const char* Filename> class serialized_set_factory_class: public boost::flyweights::factory_marker { typedef std::set<Entry,std::less<Value> > container_type; public: typedef typename container_type::iterator handle_type; typedef typename container_type::value_type entry_type;
serialized_set_factory_class() { std::ifstream ifs(Filename); if(ifs){ boost::archive::text_iarchive ia(ifs); typename container_type::size_type s=0; ia>>s; for(typename container_type::size_type n=s;n--;){ Value v; ia>>v; cont.insert(cont.end(),Entry(v)); } std::clog<<"loaded "<<s<<" entries from "<<Filename<<"\n"; } }
~serialized_set_factory_class() { std::ofstream ofs(Filename); boost::archive::text_oarchive oa(ofs); typename container_type::size_type s=cont.size(); oa<<s; for(typename container_type::iterator it=cont.begin (),it_end=cont.end(); it!=it_end;++it){ oa<<static_cast<const Value&>(*it); } std::clog<<"saved "<<s<<" entries to "<<Filename<<"\n"; }
handle_type insert(const entry_type& x) { return cont.insert(x).first; }
void erase(handle_type h) { cont.erase(h); }
const entry_type& entry(handle_type h){return *h;}
private: container_type cont; };
template<const char* Filename> struct serialized_set_factory:boost::flyweights::factory_marker { template<typename Entry,typename Value> struct apply { typedef serialized_set_factory_class< Entry,Value,Filename > type; }; };
We can use it just like this:
extern const char filename[]="fw.bd"; typedef flyweight< std::string, serialized_set_factory<filename>, no_tracking
fw_t;
Note that we're using no_tracking: if the normal refcounted tracking were used, there would be no elements remaining in the factory by the time it is destroyed, and hence nothing to persist.
The attached snippet exercises these ideas. It compiles and runs OK with GCC 3.4.4 under Cygwin. You need to link Boost.Serialization.
Hope this addresses your concerns about the potential of the lib to accomodate persistent factories.
--------------------------- Vicente Juan Botet Escriba