lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master 7fffe41 08/10: Use caching for DBDictionary (


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 7fffe41 08/10: Use caching for DBDictionary (VS)
Date: Tue, 2 Aug 2016 12:35:21 +0000 (UTC)

branch: master
commit 7fffe41cc8ca72f505e2fafc0316370641b91aca
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Use caching for DBDictionary (VS)
    
    This patch:
      http://lists.nongnu.org/archive/html/lmi/2012-06/msg00010.html
    has been applied exactly as given. Modifications to follow, e.g.,
    because the caching class has been renamed.
---
 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 0760d5f..c586af3 100644
--- a/database.cpp
+++ b/database.cpp
@@ -183,12 +183,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];
@@ -199,7 +201,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 79a922d..d354c00 100644
--- a/database.hpp
+++ b/database.hpp
@@ -31,10 +31,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.
@@ -79,6 +82,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 a569888..dc55ddc 100644
--- a/database_document.cpp
+++ b/database_document.cpp
@@ -24,6 +24,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.
@@ -32,73 +33,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()
@@ -108,30 +48,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 c661f17..4af0a0b 100644
--- a/database_document.hpp
+++ b/database_document.hpp
@@ -29,11 +29,6 @@
 #include "dbdict.hpp"
 #include "dbnames.hpp"
 
-#include <map>
-#include <string>
-
-class LMI_SO_FWD_DECL database_entity;
-
 class DatabaseDocument
     :public ProductEditorDocument
 {
@@ -43,17 +38,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 acfb0c4..045d5f5 100644
--- a/dbdict.cpp
+++ b/dbdict.cpp
@@ -84,15 +84,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()
@@ -433,7 +433,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)
 {
@@ -1074,21 +1074,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 j = z.member_names().begin(); j != z.member_names().end(); 
++j)
-            {
-            z.datum(*j).write(os);
-            }
         }
 }
 
diff --git a/dbdict.hpp b/dbdict.hpp
index 6069ca7..09221a1 100644
--- a/dbdict.hpp
+++ b/dbdict.hpp
@@ -26,6 +26,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"
@@ -40,6 +41,7 @@ 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;        // For test_product_database().
@@ -47,19 +49,20 @@ class LMI_SO DBDictionary
     friend class premium_tax_test;  // For test_rates().
 
   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 854d32c..4203924 100644
--- a/generate_product_files.cpp
+++ b/generate_product_files.cpp
@@ -38,13 +38,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   ();



reply via email to

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