00001 /* 00002 * The information in this file is 00003 * Copyright(c) 2007 Ball Aerospace & Technologies Corporation 00004 * and is subject to the terms and conditions of the 00005 * GNU Lesser General Public License Version 2.1 00006 * The license text is available from 00007 * http://www.gnu.org/licenses/lgpl.html 00008 */ 00009 00010 #ifndef CACHEDPAGER_H 00011 #define CACHEDPAGER_H 00012 00013 #include <string> 00014 00015 #include "CachedPage.h" 00016 #include "PageCache.h" 00017 #include "RasterPagerShell.h" 00018 #include "RasterPage.h" 00019 00020 #include <memory> 00021 00022 class RasterDataDescriptor; 00023 class RasterElement; 00024 namespace mta 00025 { 00026 class DMutex; 00027 } 00028 00029 /** 00030 * \ingroup ShellModule 00031 * This class represents provides cached access to pages. 00032 * 00033 * By 'cached', we mean that a block may be indexed into 00034 * by multiple data accessors (ie. multithreading an algorithm 00035 * to function with 2 threads, each reading odd and even rows). 00036 * developers would take this class and extend it to support their 00037 * algorithm specific code. 00038 */ 00039 class CachedPager : public RasterPagerShell 00040 { 00041 public: 00042 /** 00043 * The name to use for the raster element argument. 00044 * 00045 * This argument should be populated with the RasterElement 00046 * that this object will page. Arguments 00047 * with this name should be of the type RasterElement. 00048 */ 00049 static std::string PagedElementArg() 00050 { 00051 return "Paged Element"; 00052 } 00053 00054 /** 00055 * The name to use for the filename argument. 00056 * 00057 * This argument should be populated with the Filename that 00058 * this object will page. Arguments with this name should 00059 * be of the type Filename. 00060 */ 00061 static std::string PagedFilenameArg() 00062 { 00063 return "Paged Filename"; 00064 } 00065 00066 /** 00067 * Creates a CachedPager PlugIn. 00068 * 00069 * Sets cache size to 10 MB. Sets writable flag to false. 00070 * 00071 * Subclasses need to override private pure virtual methods to 00072 * open the file and get a block from that file. 00073 */ 00074 CachedPager(); 00075 00076 /** 00077 * Creates a CachedPager PlugIn. 00078 * 00079 * Sets cache size to cacheSize bytes. Sets writable flag to false. 00080 * 00081 * Subclasses need to override private pure virtual methods to 00082 * open the file and get a block from that file. 00083 * 00084 * @param cacheSize 00085 * Number of bytes in the page cache. 00086 */ 00087 CachedPager(const size_t cacheSize); 00088 00089 /** 00090 * Destructor 00091 */ 00092 ~CachedPager(); 00093 00094 /** 00095 * Get Plug-In Input Specification. 00096 * 00097 * The getInputSpecification() method is used by the 00098 * Plug-In Manager to determine the input parameters 00099 * to generically execute the Plug-In. 00100 * 00101 * @param pArgList 00102 * Returns a pointer to a %PlugInArgList specifying the 00103 * the Plug-In input parameters. 00104 * 00105 * @return This method returns true if the input parameter 00106 * argument list was successfully created. 00107 */ 00108 bool getInputSpecification(PlugInArgList *&pArgList); 00109 00110 /** 00111 * Get Plug-In Output Specification. 00112 * 00113 * The getOutputSpecification() method is used by the 00114 * Plug-In Manager to determine the output parameters 00115 * of the generically executed the Plug-In. 00116 * 00117 * @param pArgList 00118 * Returns a pointer to a %PlugInArgList specifying the 00119 * the Plug-In output parameters. 00120 * 00121 * @return This method returns true if the output parameter 00122 * argument list was successfully created. 00123 */ 00124 bool getOutputSpecification(PlugInArgList *&pArgList); 00125 00126 00127 /** 00128 * Executes the plug-in. 00129 * 00130 * @param pInputArgList 00131 * On input, pInputArgList contains a complete input 00132 * argument list for the plug-in. On return, this 00133 * argument list may be updated to reflect changes made 00134 * by the plug-in. 00135 * @param pOutputArgList 00136 * On input, pOutputArgList contains a complete output 00137 * argument list for the plug-in, although actual 00138 * values and default values will be ignored. On return, 00139 * this argument list will be updated to indicate all 00140 * output parameters made by the plug-in. 00141 * 00142 * @return True if the execution was successful. False is 00143 * returned if the user cancelled the plug-in while in 00144 * interactive mode. 00145 */ 00146 bool execute(PlugInArgList *pInputArgList, PlugInArgList *pOutputArgList); 00147 00148 /** 00149 * Parses %PlugInArgList pInputArgList. 00150 * 00151 * Assigns values from the input argument list to member variables for 00152 * use during execute. 00153 * 00154 * @param pInputArgList 00155 * The input argument list to parse. Should not be NULL. 00156 * 00157 * @return TRUE if the operation succeeds; FALSE if pInputArgList is NULL 00158 * or if the operation fails. 00159 */ 00160 virtual bool parseInputArgs(PlugInArgList *pInputArgList); 00161 00162 /** 00163 * This method should return a CachedPage (which inherits RasterPage) 00164 * interface that will allow access to an in memory pointer of the 00165 * requested data that has been loaded from the original file on disk. 00166 * 00167 * The in memory pointer should point to a section of memory 00168 * that adheres to the following constraints: 00169 * <ul> 00170 * <li> 00171 * The memory pointer should point to raw cube data that is 00172 * either formatted as specified in the pOriginalRequest parameter. 00173 * </li> 00174 * <li> 00175 * The memory pointer should point to raw cube data where 00176 * each pixel value is RasterDataDescriptor::getBytesPerElement() large. 00177 * The DataDescriptor object should be retrieved from the 00178 * RasterElement that this RasterPager is associated with. 00179 * </li> 00180 * <li> 00181 * The memory pointer should point to raw cube data where 00182 * there are only post-line bytes. If there are post-line 00183 * bytes, they should be equal to DatasetParameters::getPostlineBytes() 00184 * The DatasetParameters object should be retrieved from the 00185 * RasterElement that this RasterPager is associated with. 00186 * </li> 00187 * <li> 00188 * The memory pointer should point to raw cube data that contains 00189 * at minimum concurrentRows, concurrentBands, concurrentColumns worth of data 00190 * that is directly acccessible in memory. 00191 * </li> 00192 * </ul> 00193 * This method may be called simultaneously by multiple threads and is up to 00194 * the implementer of this method to guarantee thread-safety in that case. 00195 * 00196 * @param pOriginalRequest 00197 * The request as originally made. The fields on this object 00198 * should be examined to determine if this pager can handle 00199 * the request, and how to format it. Use the other parameters 00200 * to this method to determine where to start the RasterPage. 00201 * @param startRow 00202 * the start row of data that should be loaded from the original 00203 * data file on disk into memory. 00204 * @param startColumn 00205 * the start column of data that should be loaded from the original 00206 * data file on disk into memory. 00207 * @param startBand 00208 * the start band of data that should be loaded from the original 00209 * data file on disk into memory. 00210 * 00211 * @return a RasterPage object, that when the getRawData() pointer is called 00212 * will return a pointer to the requested cube data. This RasterPage 00213 * object should not be directly deleted, but should be passed to 00214 * the releasePage() method below when the RasterPage is no longer needed. 00215 * 00216 * If the request cannot be fulfilled, return NULL. 00217 */ 00218 RasterPage* getPage(DataRequest *pOriginalRequest, 00219 DimensionDescriptor startRow, 00220 DimensionDescriptor startColumn, 00221 DimensionDescriptor startBand); 00222 00223 /** 00224 * This method will release the RasterPage* that was requested earlier 00225 * via the getPage() method. 00226 * 00227 * NOTE: This method will check to ensure that the RasterPage is a CachedPage 00228 * prior to removal and deletion. 00229 * 00230 * This method should only release those 00231 * RasterPage* that were returned by the getPage() method of the same 00232 * instance of the RasterPager. 00233 * This method may be called simultaneously by multiple threads and is up to 00234 * the implementer of this method to guarantee thread-safety in that case. 00235 * 00236 * @param pPage 00237 * the RasterPage that should be released. 00238 */ 00239 void releasePage(RasterPage *pPage); 00240 00241 /** 00242 * Get the highest version of DataRequest that this pager supports. 00243 * 00244 * RasterPagers can support a variety of conversions from the native data 00245 * to that request in a DataRequest. getPage() should be implemented to check for 00246 * these conversions and return NULL if unsupported. 00247 * 00248 * As features are added, additional fields may be added to DataRequest. 00249 * The defaults for these fields will always be the same as on the RasterElement 00250 * being accessed. Since these fields may be added without breaking compatibility with 00251 * existing RasterPager plug-ins, there will be existing plug-ins which do not know 00252 * to check these new fields and return NULL if unsupported. 00253 * 00254 * Return a value here to state what version of DataRequest is supported. 00255 * If any higher-version fields are changed from the defaults, the core will 00256 * assume that the RasterPager is unable to handle them, and the request will not be fulfilled. 00257 * 00258 * @return The highest request version supported. 00259 * 00260 * @see DataRequest::getRequestVersion() 00261 */ 00262 int getSupportedRequestVersion() const; 00263 00264 protected: 00265 /** 00266 * Accessor function for subclasses to gain access to private member variables. 00267 * 00268 * @return The number of bytes in a single element of data. 00269 * For a 200 row x 100 column x 10 band x INT2UBYTES dataset, this 00270 * function would return 2. 00271 */ 00272 const int getBytesPerBand() const; 00273 00274 /** 00275 * Accessor function for subclasses to gain access to private member variables. 00276 * 00277 * @return The number of columns in the dataset. 00278 */ 00279 const int getColumnCount() const; 00280 00281 /** 00282 * Accessor function for subclasses to gain access to private member variables. 00283 * 00284 * @return The number of bands in the dataset. 00285 */ 00286 const int getBandCount() const; 00287 00288 /** 00289 * Accessor function for subclasses to gain access to private member variables. 00290 * 00291 * @return A pointer to the RasterElement. 00292 */ 00293 const RasterElement* getRasterElement() const; 00294 00295 /** 00296 * Returns a reasonable chunk size. 00297 * 00298 * Reasonable chunk sizes are important in keeping performance high, since reading row 00299 * by row could be as small as 16KB at a time (ie 2 bytes x 1024 columns x 8 bands) and 00300 * would not optimize for IO. Instead, the CachedPager uses chunk sizes to 00301 * read in X MB of whole rows (including bands if BIP). 00302 * 00303 * @return A reasonable chunk size, in bytes. Default implementation returns 1048576 bytes (1 MB). 00304 */ 00305 virtual double getChunkSize() const; 00306 00307 private: 00308 CachedPager& operator=(const CachedPager& rhs); 00309 00310 PageCache mCache; 00311 std::auto_ptr<mta::DMutex> mpMutex; 00312 std::string mFilename; 00313 RasterDataDescriptor* mpDescriptor; 00314 RasterElement* mpRaster; 00315 int mBytesPerBand; 00316 int mColumnCount; 00317 int mBandCount; 00318 int mRowCount; 00319 00320 /** 00321 * This method should be implemented to open the file and store a file handle to be 00322 * closed upon destruction. 00323 * 00324 * Open the file and maintain handles in derived class constructor, close in destructor. 00325 * 00326 * @param filename 00327 * The file name to open. 00328 * 00329 * @return TRUE if the open succeeds, FALSE otherwise. 00330 */ 00331 virtual bool openFile(const std::string& filename) = 0; 00332 00333 /** 00334 * Fetches a CacheUnit from disk. 00335 * 00336 * Essentially provides the same functionality as RasterPage::getPage() but for 00337 * use in a cache. CachedPages also have an offset that would allow for 00338 * higher performance if there is a circumstance where a block is read once 00339 * and two separate DataAccessors wish to access different parts of the same 00340 * page. 00341 * 00342 * @param pOriginalRequest 00343 * The request to fulfill. 00344 */ 00345 virtual CachedPage::UnitPtr fetchUnit(DataRequest *pOriginalRequest) = 0; 00346 }; 00347 00348 #endif