00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef HANDLECACHE_H_
00011 #define HANDLECACHE_H_
00012
00013 #include "Common.h"
00014 #include <assert.h>
00015 #include <map>
00016 #include <string>
00017
00018 template <class M, class H>
00019 class HandleCache {
00020 public:
00021 HandleCache(M* mgr);
00022 ~HandleCache();
00023 ReturnCode openFile(const char* fileName, H** handle);
00024 ReturnCode closeFile(H* handle);
00025 bool isOpen(const char* fileName);
00026
00027 private:
00028 M* mgr_;
00029 std::map<std::string, H*> handles_;
00030 std::map<H*, uint> counts_;
00031 std::map<H*, std::string> names_;
00032 };
00033
00034
00035 template <class M, class H>
00036 HandleCache<M,H>::HandleCache(M* mgr) {
00037 mgr_ = mgr;
00038 }
00039
00040
00041 template <class M, class H>
00042 HandleCache<M,H>::~HandleCache() {
00043 assert(handles_.empty() && counts_.empty() && names_.empty());
00044 mgr_ = 0;
00045 }
00046
00047
00048 template <class M, class H>
00049 ReturnCode HandleCache<M,H>::openFile(const char* fileName, H** handle) {
00050 typename std::map<std::string, H*>::iterator hit = handles_.find(fileName);
00051 if (hit == handles_.end()) {
00052
00053 ReturnCode code = mgr_->open(fileName, handle);
00054 if (code == RC_OK) {
00055 handles_[fileName] = *handle;
00056 counts_[*handle] = 1;
00057 names_[*handle] = fileName;
00058 }
00059 return code;
00060 } else {
00061
00062 typename std::map<H*, uint>::iterator cit = counts_.find((*hit).second);
00063 assert(cit != counts_.end());
00064 assert(names_.find((*hit).second) != names_.end());
00065 ++((*cit).second);
00066 *handle = (*hit).second;
00067 return RC_OK;
00068 }
00069 }
00070
00071
00072 template <class M, class H>
00073 ReturnCode HandleCache<M,H>::closeFile(H* handle) {
00074 typename std::map<H*, uint>::iterator cit = counts_.find(handle);
00075 assert(cit != counts_.end() && (*cit).second != 0);
00076 if ((*cit).second == 1) {
00077
00078 ReturnCode code = mgr_->close(handle);
00079 if (code == RC_OK) {
00080 counts_.erase(cit);
00081 handles_.erase(names_.find(handle)->second);
00082 names_.erase(handle);
00083 }
00084 return code;
00085 } else {
00086 --((*cit).second);
00087 return RC_OK;
00088 }
00089 }
00090
00091
00092 template <class M, class H>
00093 bool HandleCache<M,H>::isOpen(const char* fileName) {
00094 return handles_.find(fileName) != handles_.end();
00095 }
00096
00097 #endif