sprint 1-alpha
|
00001 /****************************************************************************** 00002 * sprint::cachemap 00003 * 00004 * Copyright (C) 2005-2011 Paolo Medici <www.pmx.it> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 * 00020 *******************************************************************************/ 00021 00027 #ifndef _CACHE_MAP_H 00028 #define _CACHE_MAP_H 00029 00030 #include <fstream> 00031 #include <sstream> 00032 #include <string> 00033 #include <map> 00034 00035 namespace sprint { 00036 00041 // FW 00042 template <typename _Key, typename _Tp, typename hash> 00043 class cachemap; 00044 00045 template <typename _Key, typename _Tp, typename hash> 00046 struct cachemap_iterator { 00047 typedef _Key key_type; 00048 typedef typename hash::key_type hash_key_type; 00049 typedef _Tp mapped_type; 00050 typedef std::pair<_Key, _Tp> value_type; 00051 00052 typedef typename std::map<_Key, _Tp> mapset; 00053 00054 //typedef typename cachemap<_Key, _Tp, hash> parent; 00055 00056 typename mapset::iterator m_i; 00057 cachemap_iterator(typename mapset::iterator i) : m_i(i) { } 00058 00059 }; 00060 00061 template <typename _Key, typename _Tp, typename hash> 00062 class cachemap: public hash 00063 { 00064 typedef _Key key_type; 00065 typedef typename hash::key_type hash_key_type; 00066 typedef _Tp mapped_type; 00067 typedef std::pair<_Key, _Tp> value_type; 00068 00069 typedef typename std::map<_Key, _Tp> mapset; 00070 00071 struct container: public mapset { 00072 unsigned int m_refcount; 00073 }; 00074 00075 typedef typename std::map<hash_key_type, container> innermapset; 00076 00077 00078 unsigned int m_nmap; 00079 00080 std::string m_cachename; 00081 00082 innermapset m_innermap; 00083 00084 container & load( const hash_key_type & p) 00085 { 00086 std::ostringstream s; 00087 mapped_type value; 00088 s << m_cachename << p << ".cache"; 00089 00090 std::ifstream in(s.str().c_str()); 00091 container & target = m_innermap[p]; 00092 key_type key; 00093 // TODO: implement a storageIO 00094 while( in.read(&key, sizeof(hash_key_type)) ) 00095 in.read(&target[key], sizeof(mapped_type)); 00096 return target; 00097 } 00098 00099 void save( const hash_key_type & p) const 00100 { 00101 std::ostringstream s; 00102 mapped_type value; 00103 s << m_cachename << p << ".cache"; 00104 00105 std::ofstream out(s.str().c_str()); 00106 const container & target = m_innermap[p]; 00107 for(typename container::const_iterator i = target.begin(); target.end(); i++) 00108 { 00109 out.write(&i->first, sizeof(key_type)); 00110 out.write(&i->second, sizeof(value_type)); 00111 } 00112 } 00113 00114 container & access(const key_type & k) 00115 { 00116 hash_key_type h = hash::operator()(k); 00117 typename innermapset::iterator i = m_innermap.find(k); 00118 if(i!=m_innermap.end()) 00119 return i->second; 00120 else 00121 { 00122 // remove old container 00123 return load(h); 00124 } 00125 } 00126 00127 public: 00128 00129 typedef cachemap_iterator<_Key, _Tp, hash> iterator; 00130 typedef cachemap_iterator<_Key, _Tp, hash> const_iterator; 00131 00132 public: 00133 cachemap(const std::string & cachename, unsigned int nmap) : m_cachename(cachename), m_nmap(nmap) { } 00134 ~cachemap() { } 00135 00136 mapped_type & operator[](const key_type & k) 00137 { 00138 container & c = access(k); 00139 return c[k]; 00140 } 00141 00142 iterator find(const key_type & k) 00143 { 00144 container & c = access(k); 00145 return c.find(k); 00146 } 00147 00148 iterator begin() 00149 { 00150 00151 } 00152 00153 iterator end() 00154 { 00155 00156 } 00157 00158 }; 00159 00160 } 00161 00162 #endif