EMAN2
hdf_filecache.cpp
Go to the documentation of this file.
1/*
2 * Author: Grant Tang, 05/01/2012 (gtang@bcm.edu)
3 * Copyright (c) 2000-2006 Baylor College of Medicine
4 *
5 * This software is issued under a joint BSD/GNU license. You may use the
6 * source code in this file under either license. However, note that the
7 * complete EMAN2 and SPARX software packages have some GPL dependencies,
8 * so you are responsible for compliance with the licenses of these packages
9 * if you opt to use BSD licensing. The warranty disclaimer below holds
10 * in either instance.
11 *
12 * This complete copyright notice must be included in any revised version of the
13 * source code. Additional authorship citations may be added, but existing
14 * author citations must be preserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 * */
31
32#ifdef HDFIO_CACHE
33
34#include <list>
35#include "hdf_filecache.h"
36#include <sys/time.h>
37#include <sys/resource.h>
38
39using namespace EMAN;
40using std::list;
41
42FileItem::FileItem() :
43 _path(""), _imgio(0), _timestamp(0), _readonly(true)
44{
45}
46
47FileItem::FileItem(const string& fpath, ImageIO* const fimageio, const time_t& ftimestamp, bool freadonly) :
48 _path(fpath), _imgio(fimageio), _timestamp(ftimestamp), _readonly(freadonly)
49{
50}
51
52FileItem::~FileItem()
53{
54 delete _imgio;
55}
56
57int FileItem::set_path(const string& fpath)
58{
59 _path = fpath;
60 return 0;
61}
62
63string FileItem::get_path() const
64{
65 return _path;
66}
67
68int FileItem::set_imgio(ImageIO* const fimageio)
69{
70 _imgio = fimageio;
71 return 0;
72}
73
74ImageIO * FileItem::get_imgio() const
75{
76 return _imgio;
77}
78
79int FileItem::set_timestamp(const time_t& ftimestamp)
80{
81 _timestamp = ftimestamp;
82 return 0;
83}
84
85time_t FileItem::get_timestamp() const
86{
87 return _timestamp;
88}
89
90int FileItem::set_readonly(bool freadonly)
91{
92 _readonly = freadonly;
93 return 0;
94}
95
96bool FileItem::get_readonly() const
97{
98 return _readonly;
99}
100
101
102HDFCache * HDFCache::_instance = 0;
103
104HDFCache::HDFCache()
105{
106 _thread = boost::thread(&HDFCache::cache_routine, this);
107
108 struct rlimit rl;
109 getrlimit(RLIMIT_NOFILE, &rl);
110 CACHESIZE = rl.rlim_cur/2;
111// std::cout << "CACHESIZE = " << CACHESIZE << std::endl;
112}
113
114HDFCache * HDFCache::instance()
115{
116 if(!_instance) {
117 _instance = new HDFCache();
118 }
119
120 return _instance;
121}
122
123void HDFCache::cache_routine()
124{
125 boost::posix_time::seconds intervalTime(CHECK_INTERVAL);
126
127 while(true) {
128 try {
129 force_clean();
130 purge_file();
131 boost::this_thread::sleep(intervalTime);
132 }
133 catch (std::exception& exc) {
134 std::cerr << "Very Bad Thing Happen in HDFCache routine: " << exc.what() << std::endl;
135 }
136 }
137}
138
139FileItem * HDFCache::get_file(const string& filename)
140{
141 boost::mutex::scoped_lock l(m_mutex);
142
143 if(file_pool.find(filename) != file_pool.end()) {
144 FileItem * hdf_item = file_pool[filename];
145 hdf_item->set_timestamp(time(0));
146 return hdf_item;
147 }
148 else {
149 return 0;
150 }
151}
152
153int HDFCache::add_file(FileItem * newfile)
154{
155 if(file_pool.size() >= CACHESIZE) {
156 force_clean();
157 }
158
159 boost::mutex::scoped_lock l(m_mutex);
160 file_pool[newfile->get_path()] = newfile;
161 file_pool2.push_back(newfile);
162
163 return 0;
164}
165
168int HDFCache::close_file(const string& filename)
169{
170 FileItem * hdfitem = file_pool[filename];
171
172 ImageIO * hdfio = hdfitem->get_imgio();
173 delete hdfio;
174 file_pool[filename]->set_imgio(0);
175 file_pool.erase(filename);
176
177 vector<FileItem *>::iterator it = find(file_pool2.begin(), file_pool2.end(), hdfitem);
178 file_pool2.erase(it);
179
180 return 0;
181}
182
183int HDFCache::purge_file()
184{
185 boost::mutex::scoped_lock l(m_mutex);
186
187 //close those files have access time over the threshold
188 sort(file_pool2.begin(), file_pool2.end(), least_access());
189
190 vector<FileItem *>::iterator it2 = lower_bound(file_pool2.begin(), file_pool2.end(), ACCESS_TIME_THRESHOLD, access_time_cmp());
191
192 if(it2 != file_pool2.begin()) {
193 list<FileItem *> expired_file;
194 copy(file_pool2.begin(), it2, back_inserter(expired_file));
195 list<FileItem *>::const_iterator lit;
196 for(lit = expired_file.begin(); lit!=expired_file.end(); ++lit) {
197 string filename = (*lit)->get_path();
198 close_file(filename);
199 }
200 }
201
202 return 0;
203}
204
205int HDFCache::force_clean()
206{
207 boost::mutex::scoped_lock l(m_mutex);
208
209 //close 1/10 oldest files when cache size reach limit
210 if(file_pool2.size() >= CACHESIZE) {
211 sort(file_pool2.begin(), file_pool2.end(), least_access());
212 for(size_t i=0; i<=CACHESIZE/10; ++i) {
213 close_file(file_pool2.front()->get_path());
214 }
215 }
216
217 return 0;
218}
219
220#endif //HDFIO_CACHE
ImageIO classes are designed for reading/writing various electron micrography image formats,...
Definition: imageio.h:127
EMData * copy() const
This file is a part of "emdata.h", to use functions in this file, you should "#include "emdata....
void set_path(const string &new_path)
Set the path.
string get_path() const
E2Exception class.
Definition: aligner.h:40