Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Filecache.h

Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Filecache.h
00006  *
00007  *  $Id: Filecache.h,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $
00008  *
00009  *  @author James Hu
00010  */
00011 //=============================================================================
00012 
00013 
00014 #ifndef ACE_FILECACHE_H
00015 #define ACE_FILECACHE_H
00016 #include "ace/pre.h"
00017 
00018 #include "ace/Mem_Map.h"
00019 
00020 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00021 # pragma once
00022 #endif /* ACE_LACKS_PRAGMA_ONCE */
00023 
00024 #include "ace/Synch_T.h"
00025 #include "ace/Hash_Map_Manager.h"
00026 #include "ace/SString.h"
00027 
00028 enum ACE_Filecache_Flag
00029 {
00030   ACE_NOMAP = 0,
00031   ACE_MAPIT = 1
00032 };
00033 
00034 class ACE_Filecache_Object;
00035 
00036 /**
00037  * @class ACE_Filecache_Handle
00038  *
00039  * @brief Abstraction over a real file.  This is meant to be the entry
00040  * point into the Cached Virtual Filesystem.
00041  *
00042  * This is a cached filesystem implementation based loosely on the
00043  * implementation of JAWS_File.  The interfaces will be nearly the
00044  * same.  The under-the-hood implementation should hopefully be a
00045  * much faster thing.
00046  * These will be given their own implementations later. For now, we
00047  * borrow the implementation provided by JAWS.
00048  * On creation, the cache is checked, and reference count is
00049  * incremented.  On destruction, reference count is decremented.  If
00050  * the reference count is 0, the file is removed from the cache.
00051  * E.g. 1,
00052  * {
00053  * ACE_Filecache_Handle foo("foo.html");
00054  * this->peer ().send (foo.address (), foo.size ());
00055  * }
00056  * E.g. 2,
00057  * {
00058  * ACE_Filecache_Handle foo("foo.html");
00059  * io->transmitfile (foo.handle (), this->peer ().handle ());
00060  * }
00061  * E.g. 3,
00062  * {
00063  * ACE_Filecache_Handle foo("foo.html", content_length);
00064  * this->peer ().recv (foo.address (), content_length);
00065  * }
00066  * TODO:
00067  */
00068 class ACE_Export ACE_Filecache_Handle
00069 {
00070   // (1) Get rid of the useless copying of files when reading.
00071   // Although it does make sure the file you send isn't being changed,
00072   // it doesn't make sure the file is in a sensible state before
00073   // sending it.
00074   //
00075   // Alternative: if the file get's trashed while it is being shipped,
00076   // let the client request the file again.  The cache should have an
00077   // updated copy by that point.
00078   //
00079   // (2) Use hashing for locating files.  This means I need a hastable
00080   // implementation with buckets.
00081   //
00082   // (3) Only lock when absolutely necessary.  JAWS_Virtual_Filesystem was
00083   // rather conservative, but for some reason it still ran into problems.
00084   // Since this design should be simpler, problems should be easier to spot.
00085   //
00086 public:
00087 
00088   /// Query cache for file, and acquire it.  Assumes the file is being
00089   /// opened for reading.
00090   ACE_Filecache_Handle (const ACE_TCHAR *filename,
00091                         ACE_Filecache_Flag mapit = ACE_MAPIT);
00092 
00093   /**
00094    * Create new entry, and acquire it.  Presence of SIZE assumes the
00095    * file is being opened for writing.  If SIZE is zero, assumes the
00096    * file is to be removed from the cache.
00097    */
00098   ACE_Filecache_Handle (const ACE_TCHAR *filename,
00099                         int size,
00100                         ACE_Filecache_Flag mapit = ACE_MAPIT);
00101 
00102   /// Closes any open handles, release acquired file.
00103   ~ACE_Filecache_Handle (void);
00104 
00105   /// Base address of memory mapped file.
00106   void *address (void) const;
00107 
00108   /// A handle (e.g., UNIX file descriptor, or NT file handle).
00109   ACE_HANDLE handle (void) const;
00110 
00111   /// Any associated error in handle creation and acquisition.
00112   int error (void) const;
00113 
00114   /// The size of the file.
00115   off_t size (void) const;
00116 
00117 protected:
00118   /// Default do nothing constructor.  Prevent it from being called.
00119   ACE_Filecache_Handle (void);
00120 
00121   /// Common initializations for constructors.
00122   void init (void);
00123 
00124 public:
00125   /// These come from ACE_Filecache_Object, which is an internal class.
00126   enum
00127   {
00128     ACE_SUCCESS = 0,
00129     ACE_ACCESS_FAILED,
00130     ACE_OPEN_FAILED,
00131     ACE_COPY_FAILED,
00132     ACE_STAT_FAILED,
00133     ACE_MEMMAP_FAILED,
00134     ACE_WRITE_FAILED
00135   };
00136 
00137 private:
00138   /// A reference to the low level instance.
00139   ACE_Filecache_Object *file_;
00140 
00141   /// A <dup>'d version of the one from <file_>.
00142   ACE_HANDLE handle_;
00143 
00144   int mapit_;
00145 };
00146 
00147 #if defined (ACE_HAS_TEMPLATE_SPECIALIZATION)
00148 typedef ACE_Hash_Map_Entry<const ACE_TCHAR *, ACE_Filecache_Object *>
00149         ACE_Filecache_Hash_Entry;
00150 
00151 typedef ACE_Hash_Map_Manager<const ACE_TCHAR *, ACE_Filecache_Object *, ACE_Null_Mutex>
00152         ACE_Filecache_Hash;
00153 #else
00154 typedef ACE_Hash_Map_Entry<ACE_TString, ACE_Filecache_Object *>
00155         ACE_Filecache_Hash_Entry;
00156 
00157 typedef ACE_Hash_Map_Manager<ACE_TString, ACE_Filecache_Object *, ACE_Null_Mutex>
00158         ACE_Filecache_Hash;
00159 #endif /* ACE_HAS_TEMPLATE_SPECIALIZATION */
00160 
00161 /**
00162  * @class ACE_Filecache
00163  *
00164  * @brief A hash table holding the information about entry point into
00165  * the Cached Virtual Filesystem. On insertion, the reference
00166  * count is incremented. On destruction, reference count is
00167  * decremented.
00168  */
00169 class ACE_Export ACE_Filecache
00170 {
00171 public:
00172   /// Singleton pattern.
00173   static ACE_Filecache *instance (void);
00174 
00175   ~ACE_Filecache (void);
00176 
00177   /// Returns 0 if the file associated with ``filename'' is in the cache,
00178   /// or -1 if not.
00179   int find (const ACE_TCHAR *filename);
00180 
00181   /// Return the file associated with ``filename'' if it is in the cache,
00182   /// or create if not.
00183   ACE_Filecache_Object *fetch (const ACE_TCHAR *filename, int mapit = 1);
00184 
00185   /// Remove the file associated with ``filename'' from the cache.
00186   ACE_Filecache_Object *remove (const ACE_TCHAR *filename);
00187 
00188   /// Create a new Filecache_Object, returns it.
00189   ACE_Filecache_Object *create (const ACE_TCHAR *filename, int size);
00190 
00191   /// Release an acquired Filecache_Object, returns it again or NULL if it
00192   /// was deleted.
00193   ACE_Filecache_Object *finish (ACE_Filecache_Object *&new_file);
00194 
00195 protected:
00196   ACE_Filecache_Object *insert_i (const ACE_TCHAR *filename,
00197                                   ACE_SYNCH_RW_MUTEX &filelock,
00198                                   int mapit);
00199   ACE_Filecache_Object *remove_i (const ACE_TCHAR *filename);
00200   ACE_Filecache_Object *update_i (const ACE_TCHAR *filename,
00201                                   ACE_SYNCH_RW_MUTEX &filelock,
00202                                   int mapit);
00203 
00204 public:
00205 
00206   enum
00207   {
00208     /// For this stupid implementation, use an array.  Someday, use a
00209     /// balanced search tree, or real hash table.
00210     ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE = 512,
00211 
00212     /// This determines the highwater mark in megabytes for the cache.
00213     /// This will be ignored for now.
00214     ACE_DEFAULT_VIRTUAL_FILESYSTEM_CACHE_SIZE = 20
00215   };
00216 
00217 protected:
00218   /// Prevent it from being called.
00219   ACE_Filecache (void);
00220 
00221 private:
00222   int size_;
00223 
00224   /// The hash table
00225   ACE_Filecache_Hash hash_;
00226 
00227   /// The reference to the instance
00228   static ACE_Filecache *cvf_;
00229 
00230   // = Synchronization variables.
00231   ACE_SYNCH_RW_MUTEX hash_lock_[ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE];
00232   ACE_SYNCH_RW_MUTEX file_lock_[ACE_DEFAULT_VIRTUAL_FILESYSTEM_TABLE_SIZE];
00233 };
00234 
00235 /**
00236  * @class ACE_Filecache_Object
00237  *
00238  * @brief Abstraction over a real file.  This is what the Virtual
00239  * Filesystem contains.  This class is not intended for general
00240  * consumption.  Please consult a physician before attempting to
00241  * use this class.
00242  */
00243 class ACE_Export ACE_Filecache_Object
00244 {
00245 public:
00246   friend class ACE_Filecache;
00247 
00248   /// Creates a file for reading.
00249   ACE_Filecache_Object (const ACE_TCHAR *filename,
00250                         ACE_SYNCH_RW_MUTEX &lock,
00251                         LPSECURITY_ATTRIBUTES sa = 0,
00252                         int mapit = 1);
00253 
00254   /// Creates a file for writing.
00255   ACE_Filecache_Object (const ACE_TCHAR *filename,
00256                         off_t size,
00257                         ACE_SYNCH_RW_MUTEX &lock,
00258                         LPSECURITY_ATTRIBUTES sa = 0);
00259 
00260   /// Only if reference count is zero should this be called.
00261   ~ACE_Filecache_Object (void);
00262 
00263   /// Increment the reference_count_.
00264   int acquire (void);
00265 
00266   /// Decrement the reference_count_.
00267   int release (void);
00268 
00269   // = error_ accessors
00270   int error (void) const;
00271   int error (int error_value,
00272              const ACE_TCHAR *s = ACE_LIB_TEXT ("ACE_Filecache_Object"));
00273 
00274   /// filename_ accessor
00275   const ACE_TCHAR *filename (void) const;
00276 
00277   /// handle_ accessor.
00278   ACE_HANDLE handle (void) const;
00279 
00280   /// Base memory address for memory mapped file.
00281   void *address (void) const;
00282 
00283   /// size_ accessor.
00284   off_t size (void) const;
00285 
00286   /// True if file on disk is newer than cached file.
00287   int update (void) const;
00288 
00289 protected:
00290   /// Prevent from being called.
00291   ACE_Filecache_Object (void);
00292 
00293   /// Common initialization code,
00294   void init (void);
00295 
00296 private:
00297   /// Internal error logging method, no locking.
00298   int error_i (int error_value,
00299                const ACE_TCHAR *s = ACE_LIB_TEXT ("ACE_Filecache_Object"));
00300 
00301 public:
00302 
00303   enum Creation_States
00304   {
00305     ACE_READING = 1,
00306     ACE_WRITING = 2
00307   };
00308 
00309   enum Error_Conditions
00310   {
00311     ACE_SUCCESS = 0,
00312     ACE_ACCESS_FAILED,
00313     ACE_OPEN_FAILED,
00314     ACE_COPY_FAILED,
00315     ACE_STAT_FAILED,
00316     ACE_MEMMAP_FAILED,
00317     ACE_WRITE_FAILED
00318   };
00319 
00320 private:
00321   /// The temporary file name and the real file name.  The real file is
00322   /// copied into the temporary file for safety reasons.
00323   ACE_TCHAR *tempname_;
00324   ACE_TCHAR filename_[MAXPATHLEN + 1];
00325 
00326   /// Holds the memory mapped version of the temporary file.
00327   ACE_Mem_Map mmap_;
00328 
00329   /// The descriptor to the temporary file.
00330   ACE_HANDLE handle_;
00331 
00332   /// Used to compare against the real file to test if an update is needed.
00333   ACE_stat stat_;
00334   off_t size_;
00335 
00336   /// Status indicators.
00337   int action_;
00338   int error_;
00339 
00340   /// If set to 1, means the object is flagged for removal.
00341   int stale_;
00342 
00343   /// Security attribute object.
00344   LPSECURITY_ATTRIBUTES sa_;
00345 
00346   /// The default initializer
00347   ACE_SYNCH_RW_MUTEX junklock_;
00348 
00349   /// Provides a bookkeeping mechanism for users of this object.
00350   ACE_SYNCH_RW_MUTEX &lock_;
00351 };
00352 
00353 
00354 #include "ace/post.h"
00355 #endif /* ACE_FILECACHE_H */

Generated on Mon Jun 16 11:19:42 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002