lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi] [PATCH 5/5] Uses loaded_files_cache<T> for DBDictionary.


From: Vaclav Slavik
Subject: [lmi] [PATCH 5/5] Uses loaded_files_cache<T> for DBDictionary.
Date: Fri, 15 Jun 2012 18:19:36 +0200
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:13.0) Gecko/20120601 Thunderbird/13.0

Finally, this patch re-adds caching to DBDictionary in the new form.

Notice that DatabaseDocument does not use caching: we don't want unsaved
edits to affect other users, loaded_files_cache<> is read-only.

Regards,
Vaclav


---
 database.cpp               |   10 +++---
 database.hpp               |    5 +++
 database_document.cpp      |   83 +++++---------------------------------------
 database_document.hpp      |   12 +------
 dbdict.cpp                 |   28 +++++++--------
 dbdict.hpp                 |    9 +++--
 generate_product_files.cpp |    4 +--
 7 files changed, 43 insertions(+), 108 deletions(-)

diff --git a/database.cpp b/database.cpp
index f60abe7..d9b3b61 100644
--- a/database.cpp
+++ b/database.cpp
@@ -188,12 +188,14 @@ void product_database::initialize(std::string const& 
product_name)
 {
     if(is_antediluvian_fork())
         {
-        DBDictionary::instance().InitAntediluvian();
+            boost::shared_ptr<DBDictionary> d(new DBDictionary);
+        d->InitAntediluvian();
+        db_ = d;
         }
     else
         {
         std::string 
filename(product_data(product_name).datum("DatabaseFilename"));
-        DBDictionary::instance().Init(AddDataDir(filename));
+        db_ = DBDictionary::get_cached(AddDataDir(filename));
         }
     maturity_age_ = static_cast<int>(Query(DB_MaturityAge));
     length_ = maturity_age_ - index_.index_vector()[e_axis_issue_age];
@@ -204,7 +206,7 @@ void product_database::initialize(std::string const& 
product_name)
 
 database_entity const& product_database::entity_from_key(e_database_key k) 
const
 {
-    DBDictionary const& db = DBDictionary::instance();
-    return db.datum(db_name_from_key(k));
+    LMI_ASSERT(db_);
+    return db_->datum(db_name_from_key(k));
 }
 
diff --git a/database.hpp b/database.hpp
index 338dc8c..9c5c987 100644
--- a/database.hpp
+++ b/database.hpp
@@ -33,10 +33,13 @@
 #include "so_attributes.hpp"
 #include "uncopyable_lmi.hpp"
 
+#include <boost/shared_ptr.hpp>
+
 #include <string>
 #include <vector>
 
 class database_entity;
+class DBDictionary;
 class yare_input;
 
 /// Database of product parameters.
@@ -81,6 +84,8 @@ class LMI_SO product_database
     database_index  index_;
     int             length_;
     int             maturity_age_;
+
+    boost::shared_ptr<DBDictionary const> db_;
 };
 
 #endif // database_hpp
diff --git a/database_document.cpp b/database_document.cpp
index 7304ff5..8e7ba9d 100644
--- a/database_document.cpp
+++ b/database_document.cpp
@@ -29,6 +29,7 @@
 #include "database_document.hpp"
 
 #include "alert.hpp"
+#include "contains.hpp"
 
 // EVGENIY !! Doesn't it seem strange that this wx header appears
 // to be needed here? I don't see it included in similar files.
@@ -37,73 +38,12 @@
 
 #include <wx/defs.h>
 
-#include <algorithm> // std::swap()
-
-namespace
-{
-
-/// DBDictionary class is a singleton class, which does not allow more
-/// than one instance. To load/save DBDictionary objects data from/to
-/// multiple files at the same time one could workaround the singleton
-/// constraint by:
-///   - swapping DBDictionary::instance() internal data into temporary variable
-///   - performing operation
-///   - swapping data back into singleton
-/// To ensure that in case of an exception, singleton's internal state
-/// is restored a helper class swap_workaround_for_singleton is used.
-
-class swap_workaround_for_singleton
-{
-  public:
-    swap_workaround_for_singleton
-        (std::map<std::string,database_entity>&
-        ,DBDictionary&
-        );
-    ~swap_workaround_for_singleton();
-
-  private:
-    std::map<std::string,database_entity>& m1_;
-    DBDictionary&                          m2_;
-};
-
-inline swap_workaround_for_singleton::swap_workaround_for_singleton
-    (std::map<std::string,database_entity>& m1
-    ,DBDictionary&                          m2
-    )
-    :m1_(m1)
-    ,m2_(m2)
-{
-    DatabaseDocument::swap_kludge(m1_, m2_);
-}
-
-inline swap_workaround_for_singleton::~swap_workaround_for_singleton()
-{
-    DatabaseDocument::swap_kludge(m1_, m2_);
-}
-
-} // Unnamed namespace.
-
 IMPLEMENT_DYNAMIC_CLASS(DatabaseDocument, ProductEditorDocument)
 
-void DatabaseDocument::swap_kludge
-    (std::map<std::string,database_entity>& m
-    ,DBDictionary&                          d
-    )
-{
-    typedef std::vector<std::string>::const_iterator svci;
-    for(svci i = d.member_names().begin(); i != d.member_names().end(); ++i)
-        {
-        std::swap(m[*i], d.datum(*i));
-        }
-}
-
 DatabaseDocument::DatabaseDocument()
     :ProductEditorDocument()
-    ,dict_()
 {
-    DBDictionary& instance = DBDictionary::instance();
-    swap_workaround_for_singleton workaround(dict_, instance);
-    instance.InitDB();
+    db_.InitDB();
 }
 
 DatabaseDocument::~DatabaseDocument()
@@ -113,30 +53,25 @@ DatabaseDocument::~DatabaseDocument()
 database_entity& DatabaseDocument::GetTDBValue(e_database_key index)
 {
     std::string const& s = db_name_from_key(index);
-    if(dict_.find(s) == dict_.end())
+    if(contains(db_.member_names(), s))
         {
-        // A dummy entity ought to be good enough for non-leaf treenodes.
-        static database_entity dummy;
-        return dummy;
+        return db_.datum(s);
         }
     else
         {
-        return dict_[s];
+        // A dummy entity ought to be good enough for non-leaf treenodes.
+        static database_entity dummy;
+        return dummy;
         }
 }
 
 void DatabaseDocument::ReadDocument(std::string const& filename)
 {
-    DBDictionary& instance = DBDictionary::instance();
-    swap_workaround_for_singleton workaround(dict_, instance);
-    DBDictionary::InvalidateCache();
-    instance.Init(filename);
+    db_.Init(filename);
 }
 
 void DatabaseDocument::WriteDocument(std::string const& filename)
 {
-    DBDictionary& instance = DBDictionary::instance();
-    swap_workaround_for_singleton workaround(dict_, instance);
-    instance.WriteDB(filename);
+    db_.WriteDB(filename);
 }
 
diff --git a/database_document.hpp b/database_document.hpp
index 2cf0026..638f807 100644
--- a/database_document.hpp
+++ b/database_document.hpp
@@ -31,11 +31,6 @@
 #include "dbdict.hpp"
 #include "dbnames.hpp"
 
-#include <map>
-#include <string>
-
-class LMI_SO database_entity;
-
 class DatabaseDocument
     :public ProductEditorDocument
 {
@@ -45,17 +40,12 @@ class DatabaseDocument
 
     database_entity& GetTDBValue(e_database_key index);
 
-    static void swap_kludge
-        (std::map<std::string,database_entity>&
-        ,DBDictionary&
-        );
-
   private:
     // ProductEditorDocument overrides.
     virtual void ReadDocument (std::string const& filename);
     virtual void WriteDocument(std::string const& filename);
 
-    std::map<std::string,database_entity> dict_;
+    DBDictionary db_;
 
     DECLARE_DYNAMIC_CLASS(DatabaseDocument)
 };
diff --git a/dbdict.cpp b/dbdict.cpp
index 119f124..bffb12e 100644
--- a/dbdict.cpp
+++ b/dbdict.cpp
@@ -87,15 +87,15 @@ template<> database_entity 
value_cast<database_entity>(std::string const&)
     throw "Unreachable--silences a compiler diagnostic.";
 }
 
-DBDictionary& DBDictionary::instance()
+DBDictionary::DBDictionary()
 {
-    static DBDictionary z;
-    return z;
+    ascribe_members();
 }
 
-DBDictionary::DBDictionary()
+DBDictionary::DBDictionary(std::string const& filename)
 {
     ascribe_members();
+    Init(filename);
 }
 
 DBDictionary::~DBDictionary()
@@ -402,7 +402,7 @@ void DBDictionary::ascribe_members()
     ascribe("SecondaryHurdle"     , &DBDictionary::SecondaryHurdle     );
 }
 
-/// Read and cache a database file.
+/// Read a database file.
 
 void DBDictionary::Init(std::string const& filename)
 {
@@ -972,21 +972,21 @@ void print_databases()
             }
         try
             {
-            DBDictionary::instance().Init(i->string());
+            DBDictionary const z(i->string());
+
+            fs::path out_file = fs::change_extension(*i, ".dbt");
+            fs::ofstream os(out_file, ios_out_trunc_binary());
+            typedef std::vector<std::string>::const_iterator svci;
+            for(svci i = z.member_names().begin(); i != 
z.member_names().end(); ++i)
+                {
+                z.datum(*i).write(os);
+                }
             }
         catch(...)
             {
             report_exception();
             continue;
             }
-        fs::path out_file = fs::change_extension(*i, ".dbt");
-        fs::ofstream os(out_file, ios_out_trunc_binary());
-        DBDictionary const& z = DBDictionary::instance();
-        typedef std::vector<std::string>::const_iterator svci;
-        for(svci i = z.member_names().begin(); i != z.member_names().end(); 
++i)
-            {
-            z.datum(*i).write(os);
-            }
         }
 }
 
diff --git a/dbdict.hpp b/dbdict.hpp
index 9f0c198..451632d 100644
--- a/dbdict.hpp
+++ b/dbdict.hpp
@@ -28,6 +28,7 @@
 
 #include "any_member.hpp"
 #include "dbvalue.hpp"
+#include "loaded_files_cache.hpp"
 #include "obstruct_slicing.hpp"
 #include "so_attributes.hpp"
 #include "uncopyable_lmi.hpp"
@@ -42,25 +43,27 @@ class LMI_SO DBDictionary
     ,virtual private obstruct_slicing  <DBDictionary>
     ,        public  xml_serializable  <DBDictionary>
     ,        public  MemberSymbolTable <DBDictionary>
+    ,        public  loaded_from_cache <DBDictionary>
 {
     friend class DatabaseDocument;
     friend class input_test;
     friend class product_file_test;
 
   public:
-    static DBDictionary& instance();
+    DBDictionary();
+    DBDictionary(std::string const& filename);
+
     ~DBDictionary();
 
     database_entity const& datum(std::string const&) const;
 
-    void Init(std::string const& filename);
     void WriteSampleDBFile();
     void WriteProprietaryDBFiles();
 
     void InitAntediluvian();
 
   private:
-    DBDictionary();
+    void Init(std::string const& filename);
 
     void ascribe_members();
 
diff --git a/generate_product_files.cpp b/generate_product_files.cpp
index 3436fef..a9469d3 100644
--- a/generate_product_files.cpp
+++ b/generate_product_files.cpp
@@ -43,13 +43,13 @@ int try_main(int, char*[])
 
     std::cout << "Generating product files." << std::endl;
 
-    DBDictionary::instance() .WriteSampleDBFile                  ();
+    DBDictionary()           .WriteSampleDBFile                  ();
     product_data            ::WritePolFiles                      ();
     FundData                ::WriteFundFiles                     ();
     rounding_rules          ::write_rounding_files               ();
     stratified_charges      ::write_stratified_files             ();
 
-    DBDictionary::instance() .WriteProprietaryDBFiles            ();
+    DBDictionary()           .WriteProprietaryDBFiles            ();
     FundData                ::WriteProprietaryFundFiles          ();
     product_data            ::WriteProprietaryPolFiles           ();
     rounding_rules          ::write_proprietary_rounding_files   ();
-- 
1.7.10.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]