bes  Updated for version 3.20.5
BESFileLockingCache.h
1 // BESFileLockingCache.h
2 
3 // This file was originally part of bes, A C++ back-end server
4 // implementation framework for the OPeNDAP Data Access Protocol.
5 // Copied to libdap. This is used to cache responses built from
6 // functional CE expressions.
7 
8 // Copyright (c) 2012 OPeNDAP, Inc
9 // Author: James Gallagher <jgallagher@opendap.org>,
10 // Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
11 //
12 // This library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation; either
15 // version 2.1 of the License, or (at your option) any later version.
16 //
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 //
26 // You can contact University Corporation for Atmospheric Research at
27 // 3080 Center Green Drive, Boulder, CO 80301
28 
29 #ifndef BESFileLockingCache_h_
30 #define BESFileLockingCache_h_ 1
31 
32 #include <unistd.h>
33 
34 #include <map>
35 #include <string>
36 #include <list>
37 
38 #include "BESObj.h"
39 
40 #define USE_GET_SHARED_LOCK 1
41 
42 // These typedefs are used to record information about the files in the cache.
43 // See BESFileLockingCache.cc and look at the purge() method.
44 typedef struct {
45  std::string name;
46  unsigned long long size;
47  time_t time;
48 } cache_entry;
49 
50 typedef std::list<cache_entry> CacheFiles;
51 
85 class BESFileLockingCache: public BESObj {
86 
87  friend class cacheT;
88  friend class FileLockingCacheTest;
89 
90 private:
91  static const char DAP_CACHE_CHAR = '#';
92 
93  bool d_cache_enabled;
94 
95  // pathname of the cache directory
96  std::string d_cache_dir;
97 
98  // tack this on the front of each cache file name
99  std::string d_prefix;
100 
103  unsigned long long d_max_cache_size_in_bytes;
104 
105  // When we purge, how much should we throw away. Set in the ctor to 80% of the max size.
106  unsigned long long d_target_size;
107 
108  // Name of the file that tracks the size of the cache
109  std::string d_cache_info;
110  int d_cache_info_fd;
111 
112  // map that relates files to the descriptor used to obtain a lock
113  typedef std::multimap<std::string, int> FilesAndLockDescriptors;
114  FilesAndLockDescriptors d_locks;
115 
116  bool m_check_ctor_params();
117  bool m_initialize_cache_info();
118 
119  unsigned long long m_collect_cache_dir_info(CacheFiles &contents);
120 
121  void m_record_descriptor(const std::string &file, int fd);
122  int m_remove_descriptor(const std::string &file);
123 #if USE_GET_SHARED_LOCK
124  int m_find_descriptor(const std::string &file);
125 #endif
126  // Suppress the assignment operator and default copy ctor, ...
128  BESFileLockingCache &operator=(const BESFileLockingCache &rhs);
129 
130 public:
131  // TODO Should cache_enabled be false given that cache_dir is empty? jhrg 2/18/18
132  BESFileLockingCache(): d_cache_enabled(true), d_cache_dir(""), d_prefix(""), d_max_cache_size_in_bytes(0),
133  d_target_size(0), d_cache_info(""), d_cache_info_fd(-1) { }
134 
135  BESFileLockingCache(const std::string &cache_dir, const std::string &prefix, unsigned long long size);
136 
137  virtual ~BESFileLockingCache()
138  {
139  if (d_cache_info_fd != -1) {
140  close(d_cache_info_fd);
141  d_cache_info_fd = -1;
142  }
143  }
144 
145  void initialize(const std::string &cache_dir, const std::string &prefix, unsigned long long size);
146 
147  virtual std::string get_cache_file_name(const std::string &src, bool mangle = true);
148 
149  virtual bool create_and_lock(const std::string &target, int &fd);
150  virtual bool get_read_lock(const std::string &target, int &fd);
151  virtual void exclusive_to_shared_lock(int fd);
152  virtual void unlock_and_close(const std::string &target);
153 
154  virtual void lock_cache_write();
155  virtual void lock_cache_read();
156  virtual void unlock_cache();
157 
158  virtual unsigned long long update_cache_info(const std::string &target);
159  virtual bool cache_too_big(unsigned long long current_size) const;
160  virtual unsigned long long get_cache_size();
161  virtual void update_and_purge(const std::string &new_file);
162  virtual void purge_file(const std::string &file);
163 
173  bool is_unlimited() const {
174  return d_max_cache_size_in_bytes == 0;
175  }
176 
178  const std::string get_cache_file_prefix()
179  {
180  return d_prefix;
181  }
182 
184  const std::string get_cache_directory()
185  {
186  return d_cache_dir;
187  }
188 
189  // This is a static method because it's often called from 'get_instance()'
190  // methods that are static.
191  static bool dir_exists(const std::string &dir);
192 
194  bool cache_enabled() const
195  {
196  return d_cache_enabled;
197  }
198 
200  void disable()
201  {
202  d_cache_enabled = false;
203  }
204 
206  void enable()
207  {
208  d_cache_enabled = true;
209  }
210 
211  virtual void dump(ostream &strm) const;
212 };
213 
214 #endif // BESFileLockingCache_h_
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.
const std::string get_cache_file_prefix()
virtual void update_and_purge(const std::string &new_file)
Purge files from the cache.
virtual unsigned long long update_cache_info(const std::string &target)
Update the cache info file to include 'target'.
void disable()
Disable the cache.
bool is_unlimited() const
Is this cache allowed to store as much as it wants?
static bool dir_exists(const std::string &dir)
virtual void unlock_and_close(const std::string &target)
virtual std::string get_cache_file_name(const std::string &src, bool mangle=true)
virtual unsigned long long get_cache_size()
Get the cache size.
Implementation of a caching mechanism for compressed data.
Base object for bes objects.
Definition: BESObj.h:51
virtual bool create_and_lock(const std::string &target, int &fd)
Create a file in the cache and lock it for write access.
const std::string get_cache_directory()
void initialize(const std::string &cache_dir, const std::string &prefix, unsigned long long size)
Initialize an instance of FileLockingCache.
virtual void lock_cache_write()
virtual void dump(ostream &strm) const
dumps information about this object
void enable()
Enable the cache.
virtual void lock_cache_read()
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.