CachedPager.h

Go to the documentation of this file.
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

Software Development Kit - Opticks 4.9.0 Build 16218