diff options
Diffstat (limited to '')
-rw-r--r-- | toolkit/components/places/History.h | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/toolkit/components/places/History.h b/toolkit/components/places/History.h new file mode 100644 index 0000000000..03a31186fd --- /dev/null +++ b/toolkit/components/places/History.h @@ -0,0 +1,203 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_places_History_h_ +#define mozilla_places_History_h_ + +#include <utility> + +#include "Database.h" +#include "mozIAsyncHistory.h" +#include "mozIStorageConnection.h" +#include "mozilla/BaseHistory.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Mutex.h" +#include "mozilla/dom/Link.h" +#include "mozilla/dom/PContentChild.h" +#include "nsTHashMap.h" +#include "nsIMemoryReporter.h" +#include "nsIObserver.h" +#include "nsString.h" +#include "nsTHashtable.h" +#include "nsTObserverArray.h" +#include "nsURIHashKey.h" + +namespace mozilla::places { + +struct VisitData; +class ConcurrentStatementsHolder; +class VisitedQuery; + +// Initial size of mRecentlyVisitedURIs. +#define RECENTLY_VISITED_URIS_SIZE 64 +// Microseconds after which a visit can be expired from mRecentlyVisitedURIs. +// When an URI is reloaded we only take into account the first visit to it, and +// ignore any subsequent visits, if they happen before this time has elapsed. +// A commonly found case is to reload a page every 5 minutes, so we pick a time +// larger than that. +#define RECENTLY_VISITED_URIS_MAX_AGE (6 * 60 * PR_USEC_PER_SEC) +// When notifying the main thread after inserting visits, we chunk the visits +// into medium-sized groups so that we can amortize the cost of the runnable +// without janking the main thread by expecting it to process hundreds at once. +#define NOTIFY_VISITS_CHUNK_SIZE 100 + +class History final : public BaseHistory, + public mozIAsyncHistory, + public nsIObserver, + public nsIMemoryReporter { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_MOZIASYNCHISTORY + NS_DECL_NSIOBSERVER + NS_DECL_NSIMEMORYREPORTER + + // IHistory + NS_IMETHOD VisitURI(nsIWidget*, nsIURI*, nsIURI* aLastVisitedURI, + uint32_t aFlags, uint64_t aBrowserId) final; + NS_IMETHOD SetURITitle(nsIURI*, const nsAString&) final; + + // BaseHistory + void StartPendingVisitedQueries(PendingVisitedQueries&&) final; + + History(); + + nsresult QueueVisitedStatement(RefPtr<VisitedQuery>); + + /** + * Adds an entry in moz_places with the data in aVisitData. + * + * @param aPlace + * The visit data to use to populate a new row in moz_places. + */ + nsresult InsertPlace(VisitData& aPlace); + + /** + * Updates an entry in moz_places with the data in aVisitData. + * + * @param aPlace + * The visit data to use to update the existing row in moz_places. + */ + nsresult UpdatePlace(const VisitData& aPlace); + + /** + * Loads information about the page into _place from moz_places. + * + * @param _place + * The VisitData for the place we need to know information about. + * @param [out] _exists + * Whether or the page was recorded in moz_places, false otherwise. + */ + nsresult FetchPageInfo(VisitData& _place, bool* _exists); + + /** + * Get the number of bytes of memory this History object is using, + * including sizeof(*this)) + */ + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); + + /** + * Obtains a pointer to this service. + */ + static History* GetService(); + + /** + * Used by the service manager only. + */ + static already_AddRefed<History> GetSingleton(); + + template <int N> + already_AddRefed<mozIStorageStatement> GetStatement(const char (&aQuery)[N]) { + // May be invoked on both threads. + const mozIStorageConnection* dbConn = GetConstDBConn(); + NS_ENSURE_TRUE(dbConn, nullptr); + return mDB->GetStatement(aQuery); + } + + already_AddRefed<mozIStorageStatement> GetStatement( + const nsACString& aQuery) { + // May be invoked on both threads. + const mozIStorageConnection* dbConn = GetConstDBConn(); + NS_ENSURE_TRUE(dbConn, nullptr); + return mDB->GetStatement(aQuery); + } + + bool IsShuttingDown() { + MutexAutoLock lockedScope(mShuttingDownMutex); + return mShuttingDown; + } + + /** + * Helper function to append a new URI to mRecentlyVisitedURIs. See + * mRecentlyVisitedURIs. + * @param {nsIURI} aURI The URI to append + * @param {bool} aHidden The hidden status of the visit being appended. + */ + void AppendToRecentlyVisitedURIs(nsIURI* aURI, bool aHidden); + + private: + virtual ~History(); + + void InitMemoryReporter(); + + /** + * Obtains a read-write database connection, initializing the connection + * if needed. Must be invoked on the main thread. + */ + mozIStorageConnection* GetDBConn(); + + /** + * Obtains a read-write database connection, but won't try to initialize it. + * May be invoked on both threads, but first one must invoke GetDBConn() on + * the main-thread at least once. + */ + const mozIStorageConnection* GetConstDBConn(); + + /** + * The database handle. This is initialized lazily by the first call to + * GetDBConn(), so never use it directly, or, if you really need, always + * invoke GetDBConn() before. + */ + RefPtr<mozilla::places::Database> mDB; + + RefPtr<ConcurrentStatementsHolder> mConcurrentStatementsHolder; + + /** + * Remove any memory references to tasks and do not take on any more. + */ + void Shutdown(); + + static History* gService; + + // Ensures new tasks aren't started on destruction. Should only be changed on + // the main thread. + bool mShuttingDown; + // This mutex guards mShuttingDown and should be acquired on the helper + // thread. + Mutex mShuttingDownMutex MOZ_UNANNOTATED; + // Code running in the helper thread can acquire this mutex to block shutdown + // from proceeding until done, otherwise it may be impossible to get + // statements to execute and an insert operation could be interrupted in the + // middle. + Mutex mBlockShutdownMutex MOZ_UNANNOTATED; + + // Allow private access from the helper thread to acquire mutexes. + friend class InsertVisitedURIs; + + /** + * mRecentlyVisitedURIs remembers URIs which have been recently added to + * history, to avoid saving these locations repeatedly in a short period. + */ + struct RecentURIVisit { + PRTime mTime; + bool mHidden; + }; + + nsTHashMap<nsURIHashKey, RecentURIVisit> mRecentlyVisitedURIs; +}; + +} // namespace mozilla::places + +#endif // mozilla_places_History_h_ |