Back to index

lightning-sunbird  0.9+nobinonly
nsCacheEntry.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is nsCacheEntry.h, released
00017  * February 22, 2001.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 2001
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   Gordon Sheridan <gordon@netscape.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either the GNU General Public License Version 2 or later (the "GPL"), or
00029  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 
00041 #ifndef _nsCacheEntry_h_
00042 #define _nsCacheEntry_h_
00043 
00044 #include "nsICache.h"
00045 #include "nsICacheEntryDescriptor.h"
00046 #include "nsCacheMetaData.h"
00047 
00048 #include "nspr.h"
00049 #include "pldhash.h"
00050 #include "nscore.h"
00051 #include "nsCOMPtr.h"
00052 #include "nsString.h"
00053 #include "nsAString.h"
00054 
00055 class nsCacheDevice;
00056 class nsCacheMetaData;
00057 class nsCacheRequest;
00058 class nsCacheEntryDescriptor;
00059 
00060 #define NO_EXPIRATION_TIME  0xFFFFFFFF
00061 
00062 /******************************************************************************
00063 * nsCacheEntry
00064 *******************************************************************************/
00065 class nsCacheEntry : public PRCList
00066 {
00067 public:
00068 
00069     nsCacheEntry(nsCString *          key,
00070                  PRBool               streamBased,
00071                  nsCacheStoragePolicy storagePolicy);
00072     ~nsCacheEntry();
00073 
00074 
00075     static nsresult  Create( const char *          key,
00076                              PRBool                streamBased,
00077                              nsCacheStoragePolicy  storagePolicy,
00078                              nsCacheDevice *       device,
00079                              nsCacheEntry **       result);
00080                                       
00081     nsCString *  Key()  { return mKey; }
00082 
00083     PRInt32  FetchCount()                              { return mFetchCount; }
00084     void     SetFetchCount( PRInt32   count)           { mFetchCount = count; }
00085     void     Fetched();
00086 
00087     PRUint32 LastFetched()                             { return mLastFetched; }
00088     void     SetLastFetched( PRUint32  lastFetched)    { mLastFetched = lastFetched; }
00089 
00090     PRUint32 LastModified()                            { return mLastModified; }
00091     void     SetLastModified( PRUint32 lastModified)   { mLastModified = lastModified; }
00092 
00093     PRUint32 ExpirationTime()                     { return mExpirationTime; }
00094     void     SetExpirationTime( PRUint32 expires) { mExpirationTime = expires; }
00095 
00096     PRUint32 Size()                               { return mDataSize + mMetaData.Size(); }
00097 
00098     nsCacheDevice * CacheDevice()                            { return mCacheDevice; }
00099     void            SetCacheDevice( nsCacheDevice * device)  { mCacheDevice = device; }
00100     const char *    GetDeviceID();
00101 
00105     nsISupports *Data()                           { return mData; }
00106     void         SetData( nsISupports *  data)    { mData = data; }
00107 
00108     PRUint32 DataSize()                           { return mDataSize; }
00109     void     SetDataSize( PRUint32  size)         { mDataSize = size; }
00110 
00111     void     TouchData();
00112     
00113     void     SetThread(PRThread *aThread)         { mThread = aThread; }
00114 
00118     const char * GetMetaDataElement( const char *  key) { return mMetaData.GetElement(key); }
00119     nsresult     SetMetaDataElement( const char *  key,
00120                                      const char *  value) { return mMetaData.SetElement(key, value); }
00121     nsresult VisitMetaDataElements( nsICacheMetaDataVisitor * visitor) { return mMetaData.VisitElements(visitor); }
00122     nsresult FlattenMetaData(char * buffer, PRUint32 bufSize) { return mMetaData.FlattenMetaData(buffer, bufSize); }
00123     nsresult UnflattenMetaData(const char * buffer, PRUint32 bufSize) { return mMetaData.UnflattenMetaData(buffer, bufSize); }
00124     PRUint32 MetaDataSize() { return mMetaData.Size(); }  
00125 
00126     void     TouchMetaData();
00127 
00128 
00132     nsresult GetSecurityInfo( nsISupports ** result);
00133     void     SetSecurityInfo( nsISupports *  info) { mSecurityInfo = info; }
00134 
00135 
00136     // XXX enumerate MetaData method
00137 
00138 
00139     enum CacheEntryFlags {
00140         eStoragePolicyMask   = 0x000000FF,
00141         eDoomedMask          = 0x00000100,
00142         eEntryDirtyMask      = 0x00000200,
00143         eDataDirtyMask       = 0x00000400,
00144         eMetaDataDirtyMask   = 0x00000800,
00145         eStreamDataMask      = 0x00001000,
00146         eActiveMask          = 0x00002000,
00147         eInitializedMask     = 0x00004000,
00148         eValidMask           = 0x00008000,
00149         eBindingMask         = 0x00010000
00150     };
00151     
00152     void MarkBinding()         { mFlags |=  eBindingMask; }
00153     void ClearBinding()        { mFlags &= ~eBindingMask; }
00154     PRBool IsBinding()         { return (mFlags & eBindingMask) != 0; }
00155 
00156     void MarkEntryDirty()      { mFlags |=  eEntryDirtyMask; }
00157     void MarkEntryClean()      { mFlags &= ~eEntryDirtyMask; }
00158     void MarkDataDirty()       { mFlags |=  eDataDirtyMask; }
00159     void MarkDataClean()       { mFlags &= ~eDataDirtyMask; }
00160     void MarkMetaDataDirty()   { mFlags |=  eMetaDataDirtyMask; }
00161     void MarkMetaDataClean()   { mFlags &= ~eMetaDataDirtyMask; }
00162     void MarkStreamData()      { mFlags |=  eStreamDataMask; }
00163     void MarkValid()           { mFlags |=  eValidMask; }
00164     void MarkInvalid()         { mFlags &= ~eValidMask; }
00165     //    void MarkAllowedInMemory() { mFlags |=  eAllowedInMemoryMask; }
00166     //    void MarkAllowedOnDisk()   { mFlags |=  eAllowedOnDiskMask; }
00167 
00168     PRBool IsDoomed()          { return (mFlags & eDoomedMask) != 0; }
00169     PRBool IsEntryDirty()      { return (mFlags & eEntryDirtyMask) != 0; }
00170     PRBool IsDataDirty()       { return (mFlags & eDataDirtyMask) != 0; }
00171     PRBool IsMetaDataDirty()   { return (mFlags & eMetaDataDirtyMask) != 0; }
00172     PRBool IsStreamData()      { return (mFlags & eStreamDataMask) != 0; }
00173     PRBool IsActive()          { return (mFlags & eActiveMask) != 0; }
00174     PRBool IsInitialized()     { return (mFlags & eInitializedMask) != 0; }
00175     PRBool IsValid()           { return (mFlags & eValidMask) != 0; }
00176     PRBool IsInvalid()         { return (mFlags & eValidMask) == 0; }
00177     PRBool IsInUse()           { return IsBinding() ||
00178                                         !(PR_CLIST_IS_EMPTY(&mRequestQ) &&
00179                                           PR_CLIST_IS_EMPTY(&mDescriptorQ)); }
00180     PRBool IsNotInUse()        { return !IsInUse(); }
00181 
00182 
00183     PRBool IsAllowedInMemory()
00184     {
00185         return (StoragePolicy() ==  nsICache::STORE_ANYWHERE) ||
00186             (StoragePolicy() == nsICache::STORE_IN_MEMORY);
00187     }
00188 
00189     PRBool IsAllowedOnDisk()
00190     {
00191         return (StoragePolicy() == nsICache::STORE_ANYWHERE) ||
00192             (StoragePolicy() == nsICache::STORE_ON_DISK) ||
00193             (StoragePolicy() == nsICache::STORE_ON_DISK_AS_FILE);
00194     }
00195 
00196     nsCacheStoragePolicy  StoragePolicy()
00197     {
00198         return (nsCacheStoragePolicy)(mFlags & eStoragePolicyMask);
00199     }
00200 
00201     void SetStoragePolicy(nsCacheStoragePolicy policy)
00202     {
00203         NS_ASSERTION(policy <= 0xFF, "too many bits in nsCacheStoragePolicy");
00204         mFlags &= ~eStoragePolicyMask; // clear storage policy bits
00205         mFlags |= policy;
00206     }
00207 
00208 
00209     // methods for nsCacheService
00210     nsresult RequestAccess( nsCacheRequest * request, nsCacheAccessMode *accessGranted);
00211     nsresult CreateDescriptor( nsCacheRequest *           request,
00212                                nsCacheAccessMode          accessGranted,
00213                                nsICacheEntryDescriptor ** result);
00214 
00215     //    nsresult Open(nsCacheRequest *request, nsICacheEntryDescriptor ** result);
00216     //    nsresult AsyncOpen(nsCacheRequest *request);
00217     PRBool   RemoveRequest( nsCacheRequest * request);
00218     PRBool   RemoveDescriptor( nsCacheEntryDescriptor * descriptor);
00219     
00220 private:
00221     friend class nsCacheEntryHashTable;
00222     friend class nsCacheService;
00223 
00224     void     DetachDescriptors(void);
00225 
00226     // internal methods
00227     void MarkDoomed()          { mFlags |=  eDoomedMask; }
00228     void MarkStreamBased()     { mFlags |=  eStreamDataMask; }
00229     void MarkInitialized()     { mFlags |=  eInitializedMask; }
00230     void MarkActive()          { mFlags |=  eActiveMask; }
00231     void MarkInactive()        { mFlags &= ~eActiveMask; }
00232 
00233     nsCString *             mKey;            // 4  // XXX ask scc about const'ness
00234     PRUint32                mFetchCount;     // 4
00235     PRUint32                mLastFetched;    // 4
00236     PRUint32                mLastModified;   // 4
00237     PRUint32                mLastValidated;  // 4
00238     PRUint32                mExpirationTime; // 4
00239     PRUint32                mFlags;          // 4
00240     PRUint32                mDataSize;       // 4
00241     nsCacheDevice *         mCacheDevice;    // 4
00242     nsCOMPtr<nsISupports>   mSecurityInfo;   // 
00243     nsCOMPtr<nsISupports>   mData;           // 
00244     PRThread *              mThread;
00245     nsCacheMetaData         mMetaData;       // 4
00246     PRCList                 mRequestQ;       // 8
00247     PRCList                 mDescriptorQ;    // 8
00248 };
00249 
00250 
00251 /******************************************************************************
00252 * nsCacheEntryInfo
00253 *******************************************************************************/
00254 class nsCacheEntryInfo : public nsICacheEntryInfo {
00255 public:
00256     NS_DECL_ISUPPORTS
00257     NS_DECL_NSICACHEENTRYINFO
00258 
00259     nsCacheEntryInfo(nsCacheEntry* entry)
00260         :   mCacheEntry(entry)
00261     {
00262     }
00263 
00264     virtual ~nsCacheEntryInfo() {}
00265     void    DetachEntry() { mCacheEntry = nsnull; }
00266     
00267 private:
00268     nsCacheEntry * mCacheEntry;
00269 };
00270 
00271 
00272 /******************************************************************************
00273 * nsCacheEntryHashTable
00274 *******************************************************************************/
00275 typedef struct {
00276     PLDHashNumber  keyHash;
00277     nsCacheEntry  *cacheEntry;
00278 } nsCacheEntryHashTableEntry;
00279 
00280 
00281 class nsCacheEntryHashTable
00282 {
00283 public:
00284     nsCacheEntryHashTable();
00285     ~nsCacheEntryHashTable();
00286 
00287     nsresult      Init();
00288     void          Shutdown();
00289 
00290     nsCacheEntry *GetEntry( const nsCString * key);
00291     nsresult      AddEntry( nsCacheEntry *entry);
00292     void          RemoveEntry( nsCacheEntry *entry);
00293     
00294     // XXX enumerate entries?
00295     class Visitor {
00296     public:
00297         virtual PRBool VisitEntry( nsCacheEntry *entry) = 0;
00298     };
00299     
00300     void          VisitEntries( Visitor *visitor);
00301     
00302 private:
00303     friend class nsCacheService; // XXX redefine interface so this isn't necessary
00304 
00305     // PLDHashTable operation callbacks
00306     static const void *   PR_CALLBACK GetKey( PLDHashTable *table, PLDHashEntryHdr *entry);
00307 
00308     static PLDHashNumber  PR_CALLBACK HashKey( PLDHashTable *table, const void *key);
00309 
00310     static PRBool         PR_CALLBACK MatchEntry( PLDHashTable *           table,
00311                                                   const PLDHashEntryHdr *  entry,
00312                                                   const void *             key);
00313 
00314     static void           PR_CALLBACK MoveEntry( PLDHashTable *table,
00315                                                  const PLDHashEntryHdr *from,
00316                                                  PLDHashEntryHdr       *to);
00317 
00318     static void           PR_CALLBACK ClearEntry( PLDHashTable *table, PLDHashEntryHdr *entry);
00319 
00320     static void           PR_CALLBACK Finalize( PLDHashTable *table);
00321 
00322     static
00323     PLDHashOperator       PR_CALLBACK FreeCacheEntries(PLDHashTable *    table,
00324                                                        PLDHashEntryHdr * hdr,
00325                                                        PRUint32          number,
00326                                                        void *            arg);
00327     static
00328     PLDHashOperator       PR_CALLBACK VisitEntry(PLDHashTable *         table,
00329                                                  PLDHashEntryHdr *      hdr,
00330                                                  PRUint32               number,
00331                                                  void *                 arg);
00332                                      
00333     // member variables
00334     static PLDHashTableOps ops;
00335     PLDHashTable           table;
00336     PRBool                 initialized;
00337 };
00338 
00339 #endif // _nsCacheEntry_h_
00340