Filecache.h

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

Generated on Thu Nov 9 09:41:51 2006 for ACE by doxygen 1.3.6