1#pragma clang diagnostic push
2#pragma ide diagnostic ignored "EmptyDeclOrStmt"
12#include "AggMemberDatasetDimensionCache.h"
13#include "AggMemberDataset.h"
18#include <libdap/util.h>
19#include "BESInternalError.h"
22#include "TheBESKeys.h"
24#define BES_DATA_ROOT "BES.Data.RootDirectory"
25#define BES_CATALOG_ROOT "BES.Catalog.catalog.RootDirectory"
27#define prolog "AggMemberDatasetDimensionCache::" << __func__ << "() - "
32bool AggMemberDatasetDimensionCache::d_enabled =
true;
34const string AggMemberDatasetDimensionCache::CACHE_DIR_KEY =
"NCML.DimensionCache.directory";
35const string AggMemberDatasetDimensionCache::PREFIX_KEY =
"NCML.DimensionCache.prefix";
36const string AggMemberDatasetDimensionCache::SIZE_KEY =
"NCML.DimensionCache.size";
42unsigned long AggMemberDatasetDimensionCache::getCacheSizeFromConfig()
46 unsigned long size_in_megabytes = 0;
49 std::istringstream iss(size);
50 iss >> size_in_megabytes;
53 string msg =
"[ERROR] AggMemberDatasetDimensionCache::getCacheSize() - The BES Key " + SIZE_KEY +
54 " is not set! It MUST be set to utilize the NcML Dimension Cache. ";
55 BESDEBUG(
"cache", msg << endl);
56 throw BESInternalError(msg, __FILE__, __LINE__);
58 return size_in_megabytes;
65string AggMemberDatasetDimensionCache::getCacheDirFromConfig()
72 string msg =
"[ERROR] AggMemberDatasetDimensionCache::getSubDirFromConfig() - The BES Key " + CACHE_DIR_KEY +
73 " is not set! It MUST be set to utilize the NcML Dimension Cache. ";
74 BESDEBUG(
"cache", msg << endl);
75 throw BESInternalError(msg, __FILE__, __LINE__);
86string AggMemberDatasetDimensionCache::getDimCachePrefixFromConfig()
95 string msg =
"[ERROR] AggMemberDatasetDimensionCache::getResultPrefix() - The BES Key " + PREFIX_KEY +
96 " is not set! It MUST be set to utilize the NcML Dimension Cache. ";
97 BESDEBUG(
"cache", msg << endl);
98 throw BESInternalError(msg, __FILE__, __LINE__);
110string AggMemberDatasetDimensionCache::getBesDataRootDirFromConfig()
119 ((string)
"[ERROR] AggMemberDatasetDimensionCache::getStoredResultsDir() - Neither the BES Key ") +
121 "or the BES key " + BES_DATA_ROOT +
122 " have been set! One MUST be set to utilize the NcML Dimension Cache. ";
123 BESDEBUG(
"cache", msg << endl);
124 throw BESInternalError(msg, __FILE__, __LINE__);
134AggMemberDatasetDimensionCache::AggMemberDatasetDimensionCache()
136 BESDEBUG(
"cache",
"AggMemberDatasetDimensionCache::AggMemberDatasetDimensionCache() - BEGIN" << endl);
138 d_dimCacheDir = getCacheDirFromConfig();
139 d_dataRootDir = getBesDataRootDirFromConfig();
141 d_dimCacheFilePrefix = getDimCachePrefixFromConfig();
142 d_maxCacheSize = getCacheSizeFromConfig();
145 "AggMemberDatasetDimensionCache() - Stored results cache configuration params: " << d_dimCacheDir <<
", "
146 << d_dimCacheFilePrefix
147 <<
", " << d_maxCacheSize
150 initialize(d_dimCacheDir, d_dimCacheFilePrefix, d_maxCacheSize);
152 BESDEBUG(
"cache",
"AggMemberDatasetDimensionCache::AggMemberDatasetDimensionCache() - END" << endl);
159AggMemberDatasetDimensionCache::AggMemberDatasetDimensionCache(
const string &data_root_dir,
const string &cache_dir,
160 const string &prefix,
unsigned long long size)
163 BESDEBUG(
"cache",
"AggMemberDatasetDimensionCache::AggMemberDatasetDimensionCache() - BEGIN" << endl);
165 d_dataRootDir = data_root_dir;
166 d_dimCacheDir = cache_dir;
167 d_dimCacheFilePrefix = prefix;
168 d_maxCacheSize = size;
170 initialize(d_dimCacheDir, d_dimCacheFilePrefix, d_maxCacheSize);
172 BESDEBUG(
"cache",
"AggMemberDatasetDimensionCache::AggMemberDatasetDimensionCache() - END" << endl);
182 const string &result_file_prefix,
unsigned long long max_cache_size)
184 if (d_enabled && d_instance ==
nullptr && libdap::dir_exists(cache_dir)) {
185 d_instance =
new AggMemberDatasetDimensionCache(data_root_dir, cache_dir, result_file_prefix,
187 d_enabled = d_instance->cache_enabled();
190 d_instance =
nullptr;
191 BESDEBUG(
"cache", prolog <<
"Cache is DISABLED" << endl);
195 atexit(delete_instance);
197 BESDEBUG(
"cache", prolog <<
"Cache is ENABLED" << endl);
212 if (d_enabled && d_instance == 0) {
213 d_instance =
new AggMemberDatasetDimensionCache();
214 d_enabled = d_instance->cache_enabled();
217 d_instance =
nullptr;
218 BESDEBUG(
"cache", prolog <<
"Cache is DISABLED" << endl);
222 atexit(delete_instance);
224 BESDEBUG(
"cache", prolog <<
"Cache is ENABLED" << endl);
235void AggMemberDatasetDimensionCache::delete_instance()
237 BESDEBUG(
"cache", prolog <<
"Deleting singleton BESStoredDapResultCache instance." << endl);
239 d_instance =
nullptr;
244AggMemberDatasetDimensionCache::~AggMemberDatasetDimensionCache()
260bool AggMemberDatasetDimensionCache::is_valid(
const string &cache_file_name,
const string &local_id)
const
266 off_t entry_size = 0;
267 time_t entry_time = 0;
269 if (stat(cache_file_name.c_str(), &buf) == 0) {
270 entry_size = buf.st_size;
271 entry_time = buf.st_mtime;
280 time_t dataset_time = entry_time;
281 if (stat(datasetFileName.c_str(), &buf) == 0) {
282 dataset_time = buf.st_mtime;
292 if (dataset_time > entry_time)
307 BESDEBUG(
"cache",
"AggMemberDatasetDimensionCache::loadDimensionCache() - BEGIN" << endl);
311 BESDEBUG(
"cache",
"AggMemberDatasetDimensionCache::loadDimensionCache() - local resource id: " << local_id << endl);
314 "AggMemberDatasetDimensionCache::loadDimensionCache() - cache_file_name: " << cache_file_name << endl);
324 if (!is_valid(cache_file_name, local_id)) {
326 "AggMemberDatasetDimensionCache::loadDimensionCache() - File is not valid. Purging file from cache. filename: "
327 << cache_file_name << endl);
333 "AggMemberDatasetDimensionCache::loadDimensionCache() - Dimension cache file exists. Loading dimension cache from file: "
334 << cache_file_name << endl);
336 ifstream istrm(cache_file_name.c_str());
338 throw libdap::InternalErr(__FILE__, __LINE__,
339 "Could not open '" + cache_file_name +
"' to read cached dimensions.");
359 BESDEBUG(
"cache", prolog <<
"Created and locked cache file: " << cache_file_name << endl);
362 ofstream ostrm(cache_file_name.c_str());
364 throw libdap::InternalErr(__FILE__, __LINE__,
365 "Could not open '" + cache_file_name +
"' to write cached response.");
393 "AggMemberDatasetDimensionCache::loadDimensionCache() - Couldn't create and lock cache file, But I got a read lock. "
394 "Cache file may have been rebuilt by another process. "
395 "Cache file: " << cache_file_name << endl);
398 throw libdap::InternalErr(__FILE__, __LINE__,
399 "AggMemberDatasetDimensionCache::loadDimensionCache() - Cache error during function invocation.");
403 BESDEBUG(
"cache",
"AggMemberDatasetDimensionCache::loadDimensionCache() - unlocking and closing cache file "
404 << cache_file_name << endl);
409 BESDEBUG(
"cache", prolog <<
"caught exception, unlocking cache and re-throw." << endl);
415 BESDEBUG(
"cache", prolog <<
"END (local_id=`" << local_id <<
"')" << endl);
void initialize(const std::string &cache_dir, const std::string &prefix, unsigned long long size)
Initialize an instance of FileLockingCache.
virtual void unlock_and_close(const std::string &target)
virtual unsigned long long update_cache_info(const std::string &target)
Update the cache info file to include 'target'.
virtual bool create_and_lock(const std::string &target, int &fd)
Create a file in the cache and lock it for write access.
virtual void exclusive_to_shared_lock(int fd)
Transfer from an exclusive lock to a shared lock.
virtual bool get_read_lock(const std::string &target, int &fd)
Get a read-only lock on the file if it exists.
virtual void purge_file(const std::string &file)
Purge a single file from the cache.
virtual bool cache_too_big(unsigned long long current_size) const
look at the cache size; is it too large? Look at the cache size and see if it is too big.
virtual void update_and_purge(const std::string &new_file)
Purge files from the cache.
virtual std::string get_cache_file_name(const std::string &src, bool mangle=true)
static std::string lowercase(const std::string &s)
static std::string assemblePath(const std::string &firstPart, const std::string &secondPart, bool leadingSlash=false, bool trailingSlash=false)
Assemble path fragments making sure that they are separated by a single '/' character.
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()
Access to the singleton.
void loadDimensionCache(AggMemberDataset *amd)
static AggMemberDatasetDimensionCache * get_instance()
virtual void loadDimensionCache(std::istream &istr)=0
const std::string & getLocation() const
virtual void saveDimensionCache(std::ostream &ostr)=0
virtual void fillDimensionCacheByUsingDDS()=0
Helper class for temporarily hijacking an existing dhi to load a DDX response for one particular file...