29 #include "splash/core/HandleMgr.hpp" 30 #include "splash/core/logging.hpp" 31 #include "splash/core/DCHelper.hpp" 36 HandleMgr::HandleMgr(uint32_t maxHandles, FileNameScheme fileNameScheme) :
37 maxHandles(maxHandles),
39 fileNameScheme(fileNameScheme),
41 fileCreateCallback(NULL),
42 fileCreateUserData(NULL),
43 fileOpenCallback(NULL),
44 fileOpenUserData(NULL),
45 fileCloseCallback(NULL),
46 fileCloseUserData(NULL)
49 this->maxHandles = std::numeric_limits<uint32_t>::max() - 1;
51 leastAccIndex.ctr = 0;
52 leastAccIndex.index = 0;
55 HandleMgr::~HandleMgr()
59 std::string HandleMgr::getExceptionString(std::string func,
60 std::string msg,
const char *info)
62 std::stringstream full_msg;
63 full_msg <<
"Exception for HandleMgr::" << func <<
67 full_msg <<
" (" << info <<
")";
69 return full_msg.str();
72 void HandleMgr::setFileNameScheme(FileNameScheme fileNameScheme)
throw (DCException)
74 if (this->fileNameScheme == fileNameScheme)
76 if (!filename.empty())
77 throw DCException(getExceptionString(
"setFileNameScheme",
78 "Tried to change scheme while file(s) were still open",
""));
79 this->fileNameScheme = fileNameScheme;
82 void HandleMgr::open(Dimensions mpiSize,
const std::string baseFilename,
83 hid_t fileAccProperties,
unsigned flags)
86 this->mpiSize.set(mpiSize);
87 this->filename = baseFilename;
88 this->fileAccProperties = fileAccProperties;
89 this->fileFlags = flags;
93 if (fileNameScheme != FNS_FULLNAME && baseFilename.find(
".h5") == baseFilename.length() - 3)
95 if (mpiSize.getScalarSize() > 1)
97 throw DCException(getExceptionString(
"open",
98 "Passed full filename for parallel file operations",
99 baseFilename.c_str()));
103 "\tWarning: Passed full filename for parallel file operations: %s\n" 104 "It is recommended to pass only the base name (no extension)" 105 "and let the implementation choose a filename.\n", filename.c_str());
110 void HandleMgr::open(
const std::string fullFilename,
111 hid_t fileAccProperties,
unsigned flags)
114 setFileNameScheme(FNS_FULLNAME);
115 this->mpiSize.set(1, 1, 1);
116 this->filename = fullFilename;
117 this->fileAccProperties = fileAccProperties;
118 this->fileFlags = flags;
121 uint32_t HandleMgr::indexFromPos(Dimensions& mpiPos)
123 return mpiPos[0] + mpiPos[1] * mpiSize[0] +
124 mpiPos[2] * mpiSize[0] * mpiSize[1];
127 Dimensions HandleMgr::posFromIndex(uint32_t index)
129 Dimensions pos(0, 0, 0);
133 if (fileNameScheme == FNS_MPI)
136 (index / mpiSize[0]) % mpiSize[1],
137 index / (mpiSize[1] * mpiSize[0]));
139 pos.set(index, 0, 0);
145 H5Handle HandleMgr::get(uint32_t index)
148 return get(posFromIndex(index));
151 H5Handle HandleMgr::get(Dimensions mpiPos)
155 if (fileNameScheme != FNS_FULLNAME)
156 index = indexFromPos(mpiPos);
158 HandleMap::iterator iter = handles.find(index);
159 if (iter == handles.end())
161 if (handles.size() + 1 > maxHandles)
163 HandleMap::iterator rmHandle = handles.find(leastAccIndex.index);
164 if (fileCloseCallback)
166 fileCloseCallback(rmHandle->second.handle,
167 leastAccIndex.index, fileCloseUserData);
170 if (H5Fclose(rmHandle->second.handle) < 0)
172 throw DCException(getExceptionString(
"get",
"Failed to close file handle",
173 mpiPos.toString().c_str()));
176 handles.erase(rmHandle);
177 leastAccIndex.ctr = 0;
181 std::string fullFilename;
182 if (fileNameScheme != FNS_FULLNAME && filename.find(
".h5") != filename.length() - 3)
184 std::stringstream filenameStream;
185 filenameStream << filename;
186 if (fileNameScheme == FNS_MPI)
188 filenameStream <<
"_" << mpiPos[0] <<
"_" << mpiPos[1] <<
189 "_" << mpiPos[2] <<
".h5";
190 }
else if(fileNameScheme == FNS_ITERATIONS)
191 filenameStream <<
"_" << mpiPos[0] <<
".h5";
192 fullFilename = filenameStream.str();
194 fullFilename = filename;
196 H5Handle newHandle = 0;
199 if ((fileFlags & H5F_ACC_TRUNC) && (createdFiles.find(index) == createdFiles.end()))
201 DCHelper::testFilename(fullFilename);
203 newHandle = H5Fcreate(fullFilename.c_str(), fileFlags,
204 H5P_FILE_CREATE_DEFAULT, fileAccProperties);
206 throw DCException(getExceptionString(
"get",
"Failed to create file",
207 fullFilename.c_str()));
209 createdFiles.insert(index);
211 if (fileCreateCallback)
212 fileCreateCallback(newHandle, index, fileCreateUserData);
216 unsigned tmp_flags = fileFlags;
217 if (fileFlags & H5F_ACC_TRUNC)
218 tmp_flags = H5F_ACC_RDWR;
220 newHandle = H5Fopen(fullFilename.c_str(), tmp_flags, fileAccProperties);
222 throw DCException(getExceptionString(
"get",
"Failed to open file",
223 fullFilename.c_str()));
225 if (fileOpenCallback)
226 fileOpenCallback(newHandle, index, fileOpenUserData);
230 handles[index].handle = newHandle;
231 handles[index].ctr = 1;
233 if ((leastAccIndex.ctr == 0) || (1 < leastAccIndex.ctr))
235 leastAccIndex.ctr = 1;
236 leastAccIndex.index = index;
243 if (leastAccIndex.index == index)
246 return iter->second.handle;
250 void HandleMgr::close()
253 createdFiles.clear();
255 fileAccProperties = 0;
257 leastAccIndex.ctr = 0;
258 leastAccIndex.index = 0;
259 mpiSize.set(1, 1, 1);
262 HandleMap::const_iterator iter = handles.begin();
263 for (; iter != handles.end(); ++iter)
265 if (fileCloseCallback)
266 fileCloseCallback(iter->second.handle, iter->first, fileCloseUserData);
268 if (H5Fclose(iter->second.handle) < 0)
270 throw DCException(getExceptionString(
"close",
"Failed to close file handle",
271 posFromIndex(iter->first).toString().c_str()));
278 void HandleMgr::registerFileCreate(FileCreateCallback callback,
void *userData)
280 fileCreateCallback = callback;
281 fileCreateUserData = userData;
284 void HandleMgr::registerFileOpen(FileOpenCallback callback,
void *userData)
286 fileOpenCallback = callback;
287 fileOpenUserData = userData;
290 void HandleMgr::registerFileClose(FileCloseCallback callback,
void *userData)
292 fileCloseCallback = callback;
293 fileCloseUserData = userData;
EXTERN void log_msg(int level, const char *fmt,...)