[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lmi] [PATCH 5/5] Uses loaded_files_cache<T> for DBDictionary.,
Vaclav Slavik <=