[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] (no subject)
From: |
Greg Chicares |
Subject: |
[lmi-commits] (no subject) |
Date: |
Sat, 30 Jul 2016 23:06:07 +0000 (UTC) |
branch: master
commit 99e74919772145902f539d3cfeda21cfea3fa162
Author: Gregory W. Chicares <address@hidden>
Date: Sat Jul 30 13:07:53 2016 +0000
Improve documentation of class-instance caching
---
cache_file_reads.hpp | 47 +++++++++++++++++++++++++++--------------------
1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/cache_file_reads.hpp b/cache_file_reads.hpp
index 8c027c5..a8f64a6 100644
--- a/cache_file_reads.hpp
+++ b/cache_file_reads.hpp
@@ -1,4 +1,4 @@
-// Caching of loaded files.
+// Cache class instances constructed from files.
//
// Copyright (C) 2016 Gregory W. Chicares.
//
@@ -33,15 +33,23 @@
#include <map>
#include <string>
-/// Cache of objects loaded from files.
+/// Cache of class T instances constructed from files.
///
-/// Used for holding objects that are expensively loaded from a file in memory.
-/// For example, loading actuarial_table from an XML file is costly, so we keep
-/// loaded instances in memory until the program terminates or until the file
-/// is modified.
+/// Motivation: It is costly to deserialize objects from xml, so cache
+/// them for reuse. The cache persists until the program terminates.
///
-/// T must have a constructor that takes a single string argument, the
-/// filename, as well as the default constructor.
+/// Requires: T::T() and T::T(std::string const& filename).
+///
+/// For each filename, the cache stores one instance, which is
+/// replaced by reloading the file if its write time has changed.
+///
+/// Instances are retrieved as shared_ptr<T const> so that they remain
+/// valid even when the file changes. The client is responsible for
+/// updating any stale pointers it holds.
+///
+/// Implemented as a simple Meyers singleton, with the expected
+/// dead-reference and threading issues.
+
template<typename T>
class file_cache
:private lmi::uncopyable<file_cache<T> >
@@ -51,18 +59,15 @@ class file_cache
typedef boost::shared_ptr<value_type const> value_ptr_type;
typedef std::string key_type;
- // Return singleton instance of the cache.
static file_cache<T>& instance()
{
static file_cache<T> z;
return z;
}
- // Get object corresponding to the given file, either getting it from the
- // cache or loading from the file. Checks file's timestamp and reloads it
- // if it was modified since the cached copy was read.
- value_ptr_type get(key_type const& filename)
+ value_ptr_type retrieve_or_reload(key_type const& filename)
{
+ // Throws if !exists(filename).
std::time_t const write_time = fs::last_write_time(filename);
typename map_type::iterator i = cache_.lower_bound(filename);
@@ -75,12 +80,12 @@ class file_cache
return i->second.data;
}
- // create the value before calling insert() because the call may throw
+ // Construction may throw, so do it before updating the cache.
value_ptr_type value(new value_type(filename));
- // insert() doesn't update the value if the key is already present, so
- // insert a dummy value and then modify it -- this will work for both
- // existing and new keys.
+ // insert() doesn't update the value if the key is already
+ // present, so insert a dummy value and then modify it--this
+ // works for both existing and new keys.
i = cache_.insert(i, typename map_type::value_type(filename,
record()));
record& rec = i->second;
rec.data = value;
@@ -100,8 +105,10 @@ class file_cache
map_type cache_;
};
-/// Base class for cached types.
-/// Its only purpose is providing convenience read_from_cache() function.
+/// Mixin to cache parent instances constructed from files.
+///
+/// Implemented in terms of class file_cache (q.v.).
+
template<typename T>
class cache_file_reads
{
@@ -111,7 +118,7 @@ class cache_file_reads
static ptr_type read_from_cache(std::string const& filename)
{
- return cache_type::instance().get(filename);
+ return cache_type::instance().retrieve_or_reload(filename);
}
};