1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #ifndef CacheFileContextEvictor__h__
6 #define CacheFileContextEvictor__h__
7 
8 #include "nsTArray.h"
9 #include "nsCOMPtr.h"
10 #include "nsAutoPtr.h"
11 
12 class nsIFile;
13 class nsILoadContextInfo;
14 
15 namespace mozilla {
16 namespace net {
17 
18 class CacheIndexIterator;
19 
20 struct CacheFileContextEvictorEntry
21 {
22   nsCOMPtr<nsILoadContextInfo> mInfo;
23   bool                         mPinned;
24   PRTime                       mTimeStamp; // in milliseconds
25   RefPtr<CacheIndexIterator> mIterator;
26 };
27 
28 class CacheFileContextEvictor
29 {
30 public:
31   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheFileContextEvictor)
32 
33   CacheFileContextEvictor();
34 
35 private:
36   virtual ~CacheFileContextEvictor();
37 
38 public:
39   nsresult Init(nsIFile *aCacheDirectory);
40 
41   // Returns number of contexts that are being evicted.
42   uint32_t ContextsCount();
43   // Start evicting given context.
44   nsresult AddContext(nsILoadContextInfo *aLoadContextInfo, bool aPinned);
45   // CacheFileIOManager calls this method when CacheIndex's state changes. We
46   // check whether the index is up to date and start or stop evicting according
47   // to index's state.
48   nsresult CacheIndexStateChanged();
49   // CacheFileIOManager calls this method to check whether an entry file should
50   // be considered as evicted. It returns true when there is a matching context
51   // info to the given key and the last modified time of the entry file is
52   // earlier than the time stamp of the time when the context was added to the
53   // evictor.
54   nsresult WasEvicted(const nsACString &aKey, nsIFile *aFile,
55                       bool *aEvictedAsPinned, bool *aEvictedAsNonPinned);
56 
57 private:
58   // Writes information about eviction of the given context to the disk. This is
59   // done for every context added to the evictor to be able to recover eviction
60   // after a shutdown or crash. When the context file is found after startup, we
61   // restore mTimeStamp from the last modified time of the file.
62   nsresult PersistEvictionInfoToDisk(nsILoadContextInfo *aLoadContextInfo, bool aPinned);
63   // Once we are done with eviction for the given context, the eviction info is
64   // removed from the disk.
65   nsresult RemoveEvictInfoFromDisk(nsILoadContextInfo *aLoadContextInfo, bool aPinned);
66   // Tries to load all contexts from the disk. This method is called just once
67   // after startup.
68   nsresult LoadEvictInfoFromDisk();
69   nsresult GetContextFile(nsILoadContextInfo *aLoadContextInfo, bool aPinned,
70                           nsIFile **_retval);
71 
72   void     CreateIterators();
73   void     CloseIterators();
74   void     StartEvicting();
75   nsresult EvictEntries();
76 
77   // Whether eviction is in progress
78   bool mEvicting;
79   // Whether index is up to date. We wait with eviction until the index finishes
80   // update process when it is outdated. NOTE: We also stop eviction in progress
81   // when the index is found outdated, the eviction is restarted again once the
82   // update process finishes.
83   bool mIndexIsUpToDate;
84   // Whether we already tried to restore unfinished jobs from previous run after
85   // startup.
86   static bool sDiskAlreadySearched;
87   // Array of contexts being evicted.
88   nsTArray<nsAutoPtr<CacheFileContextEvictorEntry> > mEntries;
89   nsCOMPtr<nsIFile> mCacheDirectory;
90   nsCOMPtr<nsIFile> mEntriesDir;
91 };
92 
93 } // namespace net
94 } // namespace mozilla
95 
96 #endif
97