2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #ifndef IconDatabase_h
28 #define IconDatabase_h
30 #include "IconDatabaseBase.h"
32 #include <wtf/HashMap.h>
33 #include <wtf/HashSet.h>
34 #include <wtf/Noncopyable.h>
35 #include <wtf/OwnPtr.h>
36 #include <wtf/PassOwnPtr.h>
37 #include <wtf/text/StringHash.h>
38 #include <wtf/text/WTFString.h>
40 #if ENABLE(ICONDATABASE)
41 #include "SQLiteDatabase.h"
42 #include <wtf/Threading.h>
43 #endif // ENABLE(ICONDATABASE)
50 class IconDatabaseClient;
55 class PageURLSnapshot;
58 #if ENABLE(ICONDATABASE)
62 #if !ENABLE(ICONDATABASE)
63 // For builds with IconDatabase disabled, they'll just use a default derivation of IconDatabaseBase. Which does nothing.
64 class IconDatabase : public IconDatabaseBase {
66 static void delayDatabaseCleanup() { }
67 static String defaultDatabaseFilename() { return "WebpageIcons.db"; }
71 class IconDatabase : public IconDatabaseBase {
72 WTF_MAKE_FAST_ALLOCATED;
74 // *** Main Thread Only ***
76 static PassOwnPtr<IconDatabase> create() { return adoptPtr(new IconDatabase); }
79 virtual void setClient(IconDatabaseClient*);
81 virtual bool open(const String& directory, const String& filename);
84 virtual void removeAllIcons();
86 void readIconForPageURLFromDisk(const String&);
88 virtual Image* defaultIcon(const IntSize&);
90 virtual void retainIconForPageURL(const String&);
91 virtual void releaseIconForPageURL(const String&);
92 virtual void setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String&);
93 virtual void setIconURLForPageURL(const String& iconURL, const String& pageURL);
95 virtual Image* synchronousIconForPageURL(const String&, const IntSize&);
96 virtual String synchronousIconURLForPageURL(const String&);
97 virtual bool synchronousIconDataKnownForIconURL(const String&);
98 virtual IconLoadDecision synchronousLoadDecisionForIconURL(const String&, DocumentLoader*);
100 virtual void setEnabled(bool);
101 virtual bool isEnabled() const;
103 virtual void setPrivateBrowsingEnabled(bool flag);
104 bool isPrivateBrowsingEnabled() const;
106 static void delayDatabaseCleanup();
107 static void allowDatabaseCleanup();
108 static void checkIntegrityBeforeOpening();
110 // Support for WebCoreStatistics in WebKit
111 virtual size_t pageURLMappingCount();
112 virtual size_t retainedPageURLCount();
113 virtual size_t iconRecordCount();
114 virtual size_t iconRecordCountWithData();
118 friend IconDatabaseBase& iconDatabase();
120 static void notifyPendingLoadDecisionsOnMainThread(void*);
121 void notifyPendingLoadDecisions();
123 void wakeSyncThread();
124 void scheduleOrDeferSyncTimer();
125 void syncTimerFired(Timer<IconDatabase>*);
127 Timer<IconDatabase> m_syncTimer;
128 ThreadIdentifier m_syncThread;
129 bool m_syncThreadRunning;
131 HashSet<RefPtr<DocumentLoader> > m_loadersPendingDecision;
133 RefPtr<IconRecord> m_defaultIconRecord;
135 // *** Any Thread ***
137 virtual bool isOpen() const;
138 virtual String databasePath() const;
139 static String defaultDatabaseFilename();
142 PassRefPtr<IconRecord> getOrCreateIconRecord(const String& iconURL);
143 PageURLRecord* getOrCreatePageURLRecord(const String& pageURL);
146 bool m_privateBrowsingEnabled;
148 mutable Mutex m_syncLock;
149 ThreadCondition m_syncCondition;
150 String m_databaseDirectory;
151 // Holding m_syncLock is required when accessing m_completeDatabasePath
152 String m_completeDatabasePath;
154 bool m_threadTerminationRequested;
155 bool m_removeIconsRequested;
156 bool m_iconURLImportComplete;
157 bool m_disabledSuddenTerminationForSyncThread;
159 Mutex m_urlAndIconLock;
160 // Holding m_urlAndIconLock is required when accessing any of the following data structures or the objects they contain
161 HashMap<String, IconRecord*> m_iconURLToRecordMap;
162 HashMap<String, PageURLRecord*> m_pageURLToRecordMap;
163 HashSet<String> m_retainedPageURLs;
165 Mutex m_pendingSyncLock;
166 // Holding m_pendingSyncLock is required when accessing any of the following data structures
167 HashMap<String, PageURLSnapshot> m_pageURLsPendingSync;
168 HashMap<String, IconSnapshot> m_iconsPendingSync;
170 Mutex m_pendingReadingLock;
171 // Holding m_pendingSyncLock is required when accessing any of the following data structures - when dealing with IconRecord*s, holding m_urlAndIconLock is also required
172 HashSet<String> m_pageURLsPendingImport;
173 HashSet<String> m_pageURLsInterestedInIcons;
174 HashSet<IconRecord*> m_iconsPendingReading;
176 // *** Sync Thread Only ***
178 // Should be used only on the sync thread and only by the Safari 2 Icons import procedure
179 virtual void importIconURLForPageURL(const String& iconURL, const String& pageURL);
180 virtual void importIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL);
182 virtual bool shouldStopThreadActivity() const;
185 static void* iconDatabaseSyncThreadStart(void *);
186 void* iconDatabaseSyncThread();
188 // The following block of methods are called exclusively by the sync thread to manage i/o to and from the database
189 // Each method should periodically monitor m_threadTerminationRequested when it makes sense to return early on shutdown
190 void performOpenInitialization();
191 bool checkIntegrity();
192 void performURLImport();
193 void* syncThreadMainLoop();
194 bool readFromDatabase();
195 bool writeToDatabase();
196 void pruneUnretainedIcons();
197 void checkForDanglingPageURLs(bool pruneIfFound);
198 void removeAllIconsOnThread();
199 void deleteAllPreparedStatements();
200 void* cleanupSyncThread();
202 // Record (on disk) whether or not Safari 2-style icons were imported (once per dataabse)
204 void setImported(bool);
206 bool wasExcludedFromBackup();
207 void setWasExcludedFromBackup();
209 bool m_initialPruningComplete;
211 void setIconURLForPageURLInSQLDatabase(const String&, const String&);
212 void setIconIDForPageURLInSQLDatabase(int64_t, const String&);
213 void removePageURLFromSQLDatabase(const String& pageURL);
214 int64_t getIconIDForIconURLFromSQLDatabase(const String& iconURL);
215 int64_t addIconURLToSQLDatabase(const String&);
216 PassRefPtr<SharedBuffer> getImageDataForIconURLFromSQLDatabase(const String& iconURL);
217 void removeIconFromSQLDatabase(const String& iconURL);
218 void writeIconSnapshotToSQLDatabase(const IconSnapshot&);
220 // Methods to dispatch client callbacks on the main thread
221 void dispatchDidImportIconURLForPageURLOnMainThread(const String&);
222 void dispatchDidImportIconDataForPageURLOnMainThread(const String&);
223 void dispatchDidRemoveAllIconsOnMainThread();
224 void dispatchDidFinishURLImportOnMainThread();
226 // The client is set by the main thread before the thread starts, and from then on is only used by the sync thread
227 IconDatabaseClient* m_client;
229 SQLiteDatabase m_syncDB;
231 // Track whether the "Safari 2" import is complete and/or set in the database
233 bool m_isImportedSet;
235 OwnPtr<SQLiteStatement> m_setIconIDForPageURLStatement;
236 OwnPtr<SQLiteStatement> m_removePageURLStatement;
237 OwnPtr<SQLiteStatement> m_getIconIDForIconURLStatement;
238 OwnPtr<SQLiteStatement> m_getImageDataForIconURLStatement;
239 OwnPtr<SQLiteStatement> m_addIconToIconInfoStatement;
240 OwnPtr<SQLiteStatement> m_addIconToIconDataStatement;
241 OwnPtr<SQLiteStatement> m_getImageDataStatement;
242 OwnPtr<SQLiteStatement> m_deletePageURLsForIconURLStatement;
243 OwnPtr<SQLiteStatement> m_deleteIconFromIconInfoStatement;
244 OwnPtr<SQLiteStatement> m_deleteIconFromIconDataStatement;
245 OwnPtr<SQLiteStatement> m_updateIconInfoStatement;
246 OwnPtr<SQLiteStatement> m_updateIconDataStatement;
247 OwnPtr<SQLiteStatement> m_setIconInfoStatement;
248 OwnPtr<SQLiteStatement> m_setIconDataStatement;
251 #endif // !ENABLE(ICONDATABASE)
253 } // namespace WebCore
255 #endif // IconDatabase_h