Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

Storage.h

Go to the documentation of this file.
00001 // -*- C++ -*- 00002 00003 // PLearn (A C++ Machine Learning Library) 00004 // Copyright (C) 1998 Pascal Vincent 00005 // Copyright (C) 1999-2002 Pascal Vincent, Yoshua Bengio and University of Montreal 00006 // 00007 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are met: 00010 // 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 00014 // 2. Redistributions in binary form must reproduce the above copyright 00015 // notice, this list of conditions and the following disclaimer in the 00016 // documentation and/or other materials provided with the distribution. 00017 // 00018 // 3. The name of the authors may not be used to endorse or promote 00019 // products derived from this software without specific prior written 00020 // permission. 00021 // 00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00033 // This file is part of the PLearn library. For more information on the PLearn 00034 // library, go to the PLearn Web site at www.plearn.org 00035 00036 00037 00038 00039 /* ******************************************************* 00040 * $Id: Storage.h,v 1.15 2004/07/27 16:37:30 tihocan Exp $ 00041 * AUTHORS: Pascal Vincent & Yoshua Bengio 00042 * This file is part of the PLearn library. 00043 ******************************************************* */ 00044 00045 00048 #ifndef STORAGE_INC 00049 #define STORAGE_INC 00050 00051 #include <map> 00052 #include "general.h" 00053 #include <plearn/sys/MemoryMap.h> 00054 #include "PP.h" 00055 #include <plearn/io/PStream.h> 00056 //#include "Object.h" 00057 00058 namespace PLearn { 00059 using namespace std; 00060 00061 00062 template <class T> 00063 class Storage: public PPointable 00064 { 00065 public: // A few STL-like typedefs 00066 typedef T value_type; 00067 typedef int size_type; 00068 typedef T* iterator; 00069 typedef const T* const_iterator; 00070 00071 public: 00072 int length_; 00073 T* data; 00074 bool dont_delete_data; 00075 tFileHandle fd; 00076 00077 inline Storage(const Storage& other) 00078 :length_(other.length()), dont_delete_data(false), fd((tFileHandle)STORAGE_UNUSED_HANDLE) 00079 { 00080 try 00081 { 00082 data = new T[length()]; 00083 if(!data) 00084 PLERROR("OUT OF MEMORY (new returned NULL) in copy constructor of storage, trying to allocate %d elements",length()); 00085 //memcpy(data,other.data,length()*sizeof(T)); 00086 copy(other.data, other.data+length(), data); 00087 } 00088 catch(...) 00089 { 00090 PLERROR("OUT OF MEMORY in copy constructor of storage, trying to allocate %d elements",length()); 00091 } 00092 } 00093 00094 inline Storage(int the_length, T* dataptr) 00095 :length_(the_length), data(dataptr), 00096 dont_delete_data(true), fd(STORAGE_UNUSED_HANDLE) 00097 { 00098 } 00099 00100 inline int length() const 00101 { return length_; } 00102 00103 inline int size() const 00104 { return length_; } 00105 00106 inline iterator begin() const 00107 { return data; } 00108 00109 inline iterator end() const 00110 { return data+length_; } 00111 00112 // If you're wondering why I did this stupid (and useless) function, ask GCC 3.0 that does not accept 00113 // to allocate a template into the constructor!!!! (and GCC 3.0 is the standard version on SGI) 00114 void mem_alloc(int len) 00115 { 00116 data = new T[len]; 00117 if(!data) 00118 PLERROR("OUT OF MEMORY (new returned NULL) in constructor of storage, trying to allocate %d elements",length()); 00119 clear_n(data,len); // clear the zone 00120 } 00121 00122 00124 Storage(int the_length=0) 00125 :length_(the_length), data(0), 00126 dont_delete_data(false), fd((tFileHandle)STORAGE_UNUSED_HANDLE) 00127 { 00128 int l = length(); 00129 #ifdef BOUNDCHECK 00130 if(l<0) 00131 PLERROR("new Storage called with a length() <0"); 00132 #endif 00133 if (l>0) 00134 { 00135 mem_alloc(l); 00136 } 00137 } 00138 00143 inline Storage(const char* filename, bool readonly) 00144 { 00145 void* addr; 00146 off_t filesize; 00147 if(readonly) 00148 { 00149 #if !(!defined(_MSC_VER) && !defined(_MINGW_)) 00150 PLERROR("Not implemented for MinGW"); 00152 #else 00153 addr = (T*)MemoryMap(filename, fd, true, filesize); 00154 #endif 00155 } 00156 else 00157 { 00158 #if !(!defined(_MSC_VER) && !defined(_MINGW_)) 00159 PLERROR("Not implemtned for MinGW"); 00161 #else 00162 addr = (T*)MemoryMap(filename, fd, false, filesize); 00163 #endif 00164 } 00165 00166 if(addr==0) 00167 { 00168 perror("Error when calling mmap: "); 00169 PLERROR("In Storage: Memory-mapping failed"); 00170 } 00171 00172 data = (T*) addr; 00173 length_ = filesize/sizeof(T); 00174 dont_delete_data = false; 00175 } 00176 00177 inline void pointTo(int the_length, T* dataptr) 00178 { 00179 if (data && !dont_delete_data) 00180 { 00181 if (fd!=STORAGE_UNUSED_HANDLE)//(fd>=0) //!< we are using a memory-mapped file 00182 { 00183 #if !(!defined(_MSC_VER) && !defined(_MINGW_)) 00184 00185 PLERROR("Not implemented for MinGW"); 00186 #else 00187 memoryUnmap((void *)data,fd,length()*sizeof(T)); 00188 #endif 00189 } 00190 else 00191 delete[] data; 00192 } 00193 length_=the_length; 00194 data=dataptr; 00195 fd=STORAGE_UNUSED_HANDLE; 00196 dont_delete_data=true; 00197 } 00198 00199 inline ~Storage() 00200 { 00201 if (data && !dont_delete_data) 00202 { 00203 if (fd!=STORAGE_UNUSED_HANDLE)//(fd>=0) //!< we are using a memory-mapped file 00204 { 00205 #if !(!defined(_MSC_VER) && !defined(_MINGW_)) 00206 PLERROR("Not implemented for MinGW"); 00208 #else 00209 memoryUnmap((void *)data,fd,length()*sizeof(T)); 00210 #endif 00211 } 00212 else 00213 delete[] data; 00214 } 00215 } 00216 00228 inline void resize(int newlength) 00229 { 00230 #ifdef BOUNDCHECK 00231 if(newlength<0) 00232 PLERROR("Storage::resize called with a length() <0"); 00233 #endif 00234 if (newlength==length()) 00235 return; 00236 #if defined(_MINGW_) || defined(WIN32) 00237 else if(fd>0 || dont_delete_data) 00238 #else 00239 else if(fd>=0 || dont_delete_data) 00240 #endif 00241 PLERROR("In Storage::resize cannot change size of memory-mapped data or of data allocated elsewhere"); 00242 else if (newlength==0) 00243 { 00244 if (data) delete[] data; 00245 data = 0; 00246 length_ = 0; 00247 } 00248 else if (newlength > length()) 00249 { 00250 try 00251 { 00252 T* newdata = new T[newlength]; 00253 if(!newdata) 00254 PLERROR("OUT OF MEMORY (new returned NULL) in Storage::resize, trying to allocate %d elements",newlength); 00255 if(data) 00256 { 00257 // memcpy(newdata,data,length()*sizeof(T)); 00258 copy(data,data+length(),newdata); 00259 delete[] data; 00260 } 00261 // memset(&newdata[length()],0,(newlength-length())*sizeof(T)); 00262 clear_n(newdata+length(),newlength-length()); 00263 length_ = newlength; 00264 data = newdata; 00265 } 00266 catch(...) 00267 { 00268 PLERROR("OUT OF MEMORY in Storage::resize, trying to allocate %d elements",newlength); 00269 } 00270 } 00271 else 00272 { 00273 try 00274 { 00275 T* newdata = new T[newlength]; 00276 if(!newdata) 00277 PLERROR("OUT OF MEMORY (new returned NULL) in copy constructor of storage, trying to allocate %d elements",length()); 00278 00279 if(data) 00280 { 00281 //memcpy(newdata,data,newlength*sizeof(T)); 00282 copy(data,data+newlength,newdata); 00283 delete[] data; 00284 } 00285 length_ = newlength; 00286 data = newdata; 00287 } 00288 catch(...) 00289 { 00290 PLERROR("OUT OF MEMORY in copy constructor of storage, trying to allocate %d elements",length()); 00291 } 00292 } 00293 } 00294 00296 Storage<T>* deepCopy(map<const void*, void*>& copies) const 00297 { 00298 map<const void*, void*>::iterator it = copies.find(this); 00299 if(it!=copies.end()) 00300 return (Storage<T>*) it->second; 00301 00303 Storage<T>* deep_copy = new Storage<T>(*this); 00304 for (int i = 0; i < size(); i++) { 00305 deepCopyField(deep_copy->data[i], copies); 00306 } 00308 //if (usage() > 1) 00309 copies[this] = deep_copy; 00311 return deep_copy; 00312 } 00313 00314 T& operator[](int idx) const {return data[idx];} 00315 00316 inline void push_back(const T& x) 00317 { 00318 int n = size(); 00319 resize(n+1); 00320 data[n] = x; 00321 } 00322 00323 }; 00324 00325 00326 template<class T> 00327 PStream& operator<<(PStream& out, const Storage<T>& seq) 00328 { 00329 writeSequence(out, seq); 00330 return out; 00331 } 00332 00333 template<class T> 00334 PStream& operator>>(PStream& in, Storage<T>& seq) 00335 { 00336 readSequence(in, seq); 00337 return in; 00338 } 00339 00340 00341 00342 } // end of namespace PLearn 00343 00344 #endif

Generated on Tue Aug 17 16:07:31 2004 for PLearn by doxygen 1.3.7