forked from OPENDAP/libdap4
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDAPCache3.h
More file actions
160 lines (128 loc) · 5.9 KB
/
DAPCache3.h
File metadata and controls
160 lines (128 loc) · 5.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// DAPCache3.h
// This file was originally part of bes, A C++ back-end server
// implementation framework for the OPeNDAP Data Access Protocol.
// Copied to libdap. This is used to cache responses built from
// functional CE expressions.
// Copyright (c) 2012 OPeNDAP, Inc
// Author: James Gallagher <jgallagher@opendap.org>,
// Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
// You can contact University Corporation for Atmospheric Research at
// 3080 Center Green Drive, Boulder, CO 80301
#ifndef DAPCache3_h_
#define DAPCache3_h_ 1
// #include <algorithm>
#include <map>
#include <string>
#include <list>
// #include <sstream>
#include "DapObj.h"
#if 0
#include "BESObj.h"
#include "BESDebug.h"
class BESKeys;
#endif
namespace libdap {
// These typedefs are used to record information about the files in the cache.
// See DAPCache3.cc and look at the purge() method.
typedef struct {
string name;
unsigned long long size;
time_t time;
} cache_entry;
typedef std::list<cache_entry> CacheFiles;
/** @brief Implementation of a caching mechanism for compressed data.
* This cache uses simple advisory locking found on most modern unix file systems.
* Compressed files are decompressed and stored in a cache where they can be
* used over and over until removed from the cache. Several processes can
* share the cache with each reading from files. At the same time, new files
* can be added and the cache can be purged, without disrupting the existing
* read operations.
*
* How it works. When a file is added to the cache, the cache is locked - no
* other processes can add, read or remove files. Once a file has been added,
* the cache size is examined and, if needed, the cache is purged so that its
* size is 80% of the maximum size. Then the cache is unlocked. When a process
* looks to see if a file is already in the cache, the entire cache is locked.
* If the file is present, a shared read lock is obtained and the cache is unlocked.
*
* Methods: create_and_lock() and get_read_lock() open and lock files; the former
* creates the file and locks it exclusively iff it does not exist, while the
* latter obtains a shared lock iff the file already exists. The unlock()
* methods unlock a file. The lock_cache_info() and unlock_cache_info() are
* used to control access to the whole cache - with the open + lock and
* close + unlock operations performed atomically. Other methods that operate
* on the cache info file must only be called when the lock has been obtained.
*/
class DAPCache3: public libdap::DapObj {
private:
static DAPCache3 * d_instance;
static const char DAP_CACHE_CHAR = '#';
string d_cache_dir; /// pathname of the cache directory
string d_prefix; /// tack this on the front of cache file name
/// How many megabytes can the cache hold before we have to purge
unsigned long long d_max_cache_size_in_bytes;
// When we purge, how much should we throw away. Set in the ctor to 80% of the max size.
unsigned long long d_target_size;
#if 0
// This class implements a singleton, so the constructor is hidden.
BESCache3(BESKeys *keys, const string &cache_dir_key, const string &prefix_key, const string &size_key);
#endif
// Testing
DAPCache3(const string &cache_dir, const string &prefix, unsigned long long size);
// Suppress the assignment operator and default copy ctor, ...
DAPCache3();
DAPCache3(const DAPCache3 &);
DAPCache3 &operator=(const DAPCache3 &rhs);
void m_check_ctor_params();
void m_initialize_cache_info();
unsigned long long m_collect_cache_dir_info(CacheFiles &contents);
/// Name of the file that tracks the size of the cache
string d_cache_info;
int d_cache_info_fd;
void m_record_descriptor(const string &file, int fd);
int m_get_descriptor(const string &file);
// map that relates files to the descriptor used to obtain a lock
typedef std::map<string, int> FilesAndLockDescriptors;
FilesAndLockDescriptors d_locks;
// Life-cycle control
virtual ~DAPCache3() { }
static void delete_instance();
public:
static DAPCache3 *get_instance(const string &cache_dir, const string &prefix, unsigned long long size);
static DAPCache3 *get_instance();
string get_cache_file_name(const string &src, bool mangle = true);
virtual bool create_and_lock(const string &target, int &fd);
virtual bool get_read_lock(const string &target, int &fd);
virtual void exclusive_to_shared_lock(int fd);
virtual void unlock_and_close(const string &target);
virtual void unlock_and_close(int fd);
virtual void lock_cache_write();
virtual void lock_cache_read();
virtual void unlock_cache();
virtual unsigned long long update_cache_info(const string &target);
virtual bool cache_too_big(unsigned long long current_size) const;
virtual unsigned long long get_cache_size();
virtual void update_and_purge(const string &new_file);
virtual void purge_file(const string &file);
#if 0
static BESCache3 *get_instance(BESKeys *keys, const string &cache_dir_key, const string &prefix_key, const string &size_key);
#endif
virtual void dump(ostream &strm) const ;
};
} // namespace libdap
#endif // DAPCache3_h_