a695b29f27efcd8bf77fb58edc934384173f54f6
[WebKit-https.git] / WebCore / loader / icon / IconDatabase.h
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25  
26 #ifndef IconDatabase_h
27 #define IconDatabase_h
28
29 #if ENABLE(ICONDATABASE)
30 #include "SQLiteDatabase.h"
31 #endif
32
33 #include "StringHash.h"
34 #if ENABLE(ICONDATABASE)
35 #include "Threading.h"
36 #endif
37 #include "Timer.h"
38 #include <wtf/HashSet.h>
39 #include <wtf/Noncopyable.h>
40 #include <wtf/OwnPtr.h>
41
42 namespace WebCore { 
43
44 class DocumentLoader;
45 class Image;
46 class IntSize;
47 class IconDatabaseClient;
48 class IconRecord;
49 class IconSnapshot;
50 class KURL;
51 class PageURLRecord;
52 class PageURLSnapshot;
53 class SharedBuffer;
54
55 #if ENABLE(ICONDATABASE)
56 class SQLTransaction;
57 #endif
58
59 enum IconLoadDecision {
60     IconLoadYes,
61     IconLoadNo,
62     IconLoadUnknown
63 };
64
65 class IconDatabase : Noncopyable {
66
67 // *** Main Thread Only ***
68 public:
69     void setClient(IconDatabaseClient*);
70
71     bool open(const String& path);
72     void close();
73             
74     void removeAllIcons();
75
76     Image* iconForPageURL(const String&, const IntSize&, bool cache = true);
77     void readIconForPageURLFromDisk(const String&);
78     String iconURLForPageURL(const String&);
79     Image* defaultIcon(const IntSize&);
80
81     void retainIconForPageURL(const String&);
82     void releaseIconForPageURL(const String&);
83
84     void setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String&);
85     void setIconURLForPageURL(const String& iconURL, const String& pageURL);
86
87     IconLoadDecision loadDecisionForIconURL(const String&, DocumentLoader*);
88     bool iconDataKnownForIconURL(const String&);
89     
90     void setEnabled(bool enabled);
91     bool isEnabled() const;
92     
93     void setPrivateBrowsingEnabled(bool flag);
94     bool isPrivateBrowsingEnabled() const;
95     
96     static void delayDatabaseCleanup();
97     static void allowDatabaseCleanup();
98     static void checkIntegrityBeforeOpening();
99         
100     // Support for WebCoreStatistics in WebKit
101     size_t pageURLMappingCount();
102     size_t retainedPageURLCount();
103     size_t iconRecordCount();
104     size_t iconRecordCountWithData();
105
106 private:
107     IconDatabase();
108     ~IconDatabase();
109     friend IconDatabase* iconDatabase();
110
111 #if ENABLE(ICONDATABASE)
112     // This is called on the main thread via the callOnMainThread() function which currently
113     // doesn't have any way to allow it to be an instance method, which it should be
114     static void notifyPendingLoadDecisions();
115     
116     void notifyPendingLoadDecisionsInternal();
117
118     void wakeSyncThread();
119     void scheduleOrDeferSyncTimer();
120     OwnPtr<Timer<IconDatabase> > m_syncTimer;
121     void syncTimerFired(Timer<IconDatabase>*);
122     
123     pthread_t m_syncThread;
124     bool m_syncThreadRunning;
125     
126     HashSet<RefPtr<DocumentLoader> > m_loadersPendingDecision;
127
128     IconRecord* m_defaultIconRecord;
129 #endif // ENABLE(ICONDATABASE)
130
131 // *** Any Thread ***
132 public:
133     bool isOpen() const;
134     String databasePath() const;
135     static String defaultDatabaseFilename();
136
137 private:
138 #if ENABLE(ICONDATABASE)
139     IconRecord* getOrCreateIconRecord(const String& iconURL);
140     PageURLRecord* getOrCreatePageURLRecord(const String& pageURL);
141     
142     bool m_isEnabled;
143     bool m_privateBrowsingEnabled;
144     
145     mutable Mutex m_syncLock;
146     ThreadCondition m_syncCondition;
147     String m_databaseDirectory;
148     // Holding m_syncLock is required when accessing m_completeDatabasePath
149     String m_completeDatabasePath;
150     
151     bool m_threadTerminationRequested;
152     bool m_removeIconsRequested;
153     bool m_iconURLImportComplete;
154     
155     Mutex m_urlAndIconLock;
156     // Holding m_urlAndIconLock is required when accessing any of the following data structures or the objects they contain
157     HashMap<String, IconRecord*> m_iconURLToRecordMap;
158     HashMap<String, PageURLRecord*> m_pageURLToRecordMap;
159     HashSet<String> m_retainedPageURLs;
160
161     Mutex m_pendingSyncLock;
162     // Holding m_pendingSyncLock is required when accessing any of the following data structures
163     HashMap<String, PageURLSnapshot> m_pageURLsPendingSync;
164     HashMap<String, IconSnapshot> m_iconsPendingSync;
165     
166     Mutex m_pendingReadingLock;    
167     // Holding m_pendingSyncLock is required when accessing any of the following data structures - when dealing with IconRecord*s, holding m_urlAndIconLock is also required
168     HashSet<String> m_pageURLsPendingImport;
169     HashSet<String> m_pageURLsInterestedInIcons;
170     HashSet<IconRecord*> m_iconsPendingReading;
171
172 // *** Sync Thread Only ***
173 public:
174     // Should be used only on the sync thread and only by the Safari 2 Icons import procedure
175     void importIconURLForPageURL(const String& iconURL, const String& pageURL);
176     void importIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL);
177     
178     bool shouldStopThreadActivity() const;
179
180 private:    
181     static void* iconDatabaseSyncThreadStart(void *);
182     void* iconDatabaseSyncThread();
183     
184     // The following block of methods are called exclusively by the sync thread to manage i/o to and from the database
185     // Each method should periodically monitor m_threadTerminationRequested when it makes sense to return early on shutdown
186     void performOpenInitialization();
187     bool checkIntegrity();
188     void performURLImport();
189     void* syncThreadMainLoop();
190     bool readFromDatabase();
191     bool writeToDatabase();
192     void pruneUnretainedIcons();
193     void checkForDanglingPageURLs(bool pruneIfFound);
194     void removeAllIconsOnThread();
195     void deleteAllPreparedStatements();
196     void* cleanupSyncThread();
197
198     // Record (on disk) whether or not Safari 2-style icons were imported (once per dataabse)
199     bool imported();
200     void setImported(bool);
201     
202     bool m_initialPruningComplete;
203         
204     void setIconURLForPageURLInSQLDatabase(const String&, const String&);
205     void setIconIDForPageURLInSQLDatabase(int64_t, const String&);
206     void removePageURLFromSQLDatabase(const String& pageURL);
207     int64_t getIconIDForIconURLFromSQLDatabase(const String& iconURL);
208     int64_t addIconURLToSQLDatabase(const String&);
209     PassRefPtr<SharedBuffer> getImageDataForIconURLFromSQLDatabase(const String& iconURL);
210     void removeIconFromSQLDatabase(const String& iconURL);
211     void writeIconSnapshotToSQLDatabase(const IconSnapshot&);    
212     
213     // The client is set by the main thread before the thread starts, and from then on is only used by the sync thread
214     IconDatabaseClient* m_client;
215     
216     SQLiteDatabase m_syncDB;
217     
218     // Track whether the "Safari 2" import is complete and/or set in the database
219     bool m_imported;
220     bool m_isImportedSet;
221     
222     OwnPtr<SQLiteStatement> m_setIconIDForPageURLStatement;
223     OwnPtr<SQLiteStatement> m_removePageURLStatement;
224     OwnPtr<SQLiteStatement> m_getIconIDForIconURLStatement;
225     OwnPtr<SQLiteStatement> m_getImageDataForIconURLStatement;
226     OwnPtr<SQLiteStatement> m_addIconToIconInfoStatement;
227     OwnPtr<SQLiteStatement> m_addIconToIconDataStatement;
228     OwnPtr<SQLiteStatement> m_getImageDataStatement;
229     OwnPtr<SQLiteStatement> m_deletePageURLsForIconURLStatement;
230     OwnPtr<SQLiteStatement> m_deleteIconFromIconInfoStatement;
231     OwnPtr<SQLiteStatement> m_deleteIconFromIconDataStatement;
232     OwnPtr<SQLiteStatement> m_updateIconInfoStatement;
233     OwnPtr<SQLiteStatement> m_updateIconDataStatement;
234     OwnPtr<SQLiteStatement> m_setIconInfoStatement;
235     OwnPtr<SQLiteStatement> m_setIconDataStatement;
236 #endif // ENABLE(ICONDATABASE)
237 };
238
239 // Function to obtain the global icon database.
240 IconDatabase* iconDatabase();
241
242 } // namespace WebCore
243
244 #endif