Boost logo

Boost :

From: JOAQUIN LOPEZ MU?Z (joaquin_at_[hidden])
Date: 2008-01-28 17:13:15


"vicente.botet" ha escrito:

> Maybe this should be managed orthogonally but, can the current
design
> managewith 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:

  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.

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk