michael@0: /* vim: set ts=2 sts=2 et sw=2: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_net_Seer_h michael@0: #define mozilla_net_Seer_h michael@0: michael@0: #include "nsINetworkSeer.h" michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsIDNSListener.h" michael@0: #include "nsIInterfaceRequestor.h" michael@0: #include "nsIObserver.h" michael@0: #include "nsISpeculativeConnect.h" michael@0: #include "nsProxyRelease.h" michael@0: michael@0: #include "mozilla/Mutex.h" michael@0: #include "mozilla/storage/StatementCache.h" michael@0: #include "mozilla/TimeStamp.h" michael@0: michael@0: class nsIDNSService; michael@0: class nsINetworkSeerVerifier; michael@0: class nsIThread; michael@0: class nsITimer; michael@0: michael@0: class mozIStorageConnection; michael@0: class mozIStorageService; michael@0: class mozIStorageStatement; michael@0: michael@0: namespace mozilla { michael@0: namespace net { michael@0: michael@0: typedef nsMainThreadPtrHandle SeerVerifierHandle; michael@0: michael@0: class SeerPredictionRunner; michael@0: struct SeerTelemetryAccumulators; michael@0: class SeerDNSListener; michael@0: michael@0: class Seer : public nsINetworkSeer michael@0: , public nsIObserver michael@0: , public nsISpeculativeConnectionOverrider michael@0: , public nsIInterfaceRequestor michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSINETWORKSEER michael@0: NS_DECL_NSIOBSERVER michael@0: NS_DECL_NSISPECULATIVECONNECTIONOVERRIDER michael@0: NS_DECL_NSIINTERFACEREQUESTOR michael@0: michael@0: Seer(); michael@0: virtual ~Seer(); michael@0: michael@0: nsresult Init(); michael@0: void Shutdown(); michael@0: static nsresult Create(nsISupports *outer, const nsIID& iid, void **result); michael@0: michael@0: private: michael@0: friend class SeerPredictionEvent; michael@0: friend class SeerLearnEvent; michael@0: friend class SeerResetEvent; michael@0: friend class SeerPredictionRunner; michael@0: friend class SeerDBShutdownRunner; michael@0: friend class SeerCommitTimerInitEvent; michael@0: friend class SeerNewTransactionEvent; michael@0: friend class SeerCleanupEvent; michael@0: michael@0: void CheckForAndDeleteOldDBFile(); michael@0: nsresult EnsureInitStorage(); michael@0: michael@0: // This is a proxy for the information we need from an nsIURI michael@0: struct UriInfo { michael@0: nsAutoCString spec; michael@0: nsAutoCString origin; michael@0: }; michael@0: michael@0: void PredictForLink(nsIURI *targetURI, michael@0: nsIURI *sourceURI, michael@0: nsINetworkSeerVerifier *verifier); michael@0: void PredictForPageload(const UriInfo &dest, michael@0: SeerVerifierHandle &verifier, michael@0: int stackCount, michael@0: TimeStamp &predictStartTime); michael@0: void PredictForStartup(SeerVerifierHandle &verifier, michael@0: TimeStamp &predictStartTime); michael@0: michael@0: // Whether we're working on a page or an origin michael@0: enum QueryType { michael@0: QUERY_PAGE = 0, michael@0: QUERY_ORIGIN michael@0: }; michael@0: michael@0: // Holds info from the db about a top-level page or origin michael@0: struct TopLevelInfo { michael@0: int32_t id; michael@0: int32_t loadCount; michael@0: PRTime lastLoad; michael@0: }; michael@0: michael@0: // Holds info from the db about a subresource michael@0: struct SubresourceInfo { michael@0: int32_t id; michael@0: int32_t hitCount; michael@0: PRTime lastHit; michael@0: }; michael@0: michael@0: nsresult ReserveSpaceInQueue(); michael@0: void FreeSpaceInQueue(); michael@0: michael@0: int CalculateGlobalDegradation(PRTime now, michael@0: PRTime lastLoad); michael@0: int CalculateConfidence(int baseConfidence, michael@0: PRTime lastHit, michael@0: PRTime lastPossible, michael@0: int globalDegradation); michael@0: void SetupPrediction(int confidence, michael@0: const nsACString &uri, michael@0: SeerPredictionRunner *runner); michael@0: michael@0: bool LookupTopLevel(QueryType queryType, michael@0: const nsACString &key, michael@0: TopLevelInfo &info); michael@0: void AddTopLevel(QueryType queryType, michael@0: const nsACString &key, michael@0: PRTime now); michael@0: void UpdateTopLevel(QueryType queryType, michael@0: const TopLevelInfo &info, michael@0: PRTime now); michael@0: bool TryPredict(QueryType queryType, michael@0: const TopLevelInfo &info, michael@0: PRTime now, michael@0: SeerVerifierHandle &verifier, michael@0: TimeStamp &predictStartTime); michael@0: bool WouldRedirect(const TopLevelInfo &info, michael@0: PRTime now, michael@0: UriInfo &newUri); michael@0: michael@0: bool LookupSubresource(QueryType queryType, michael@0: const int32_t parentId, michael@0: const nsACString &key, michael@0: SubresourceInfo &info); michael@0: void AddSubresource(QueryType queryType, michael@0: const int32_t parentId, michael@0: const nsACString &key, PRTime now); michael@0: void UpdateSubresource(QueryType queryType, michael@0: const SubresourceInfo &info, michael@0: PRTime now); michael@0: michael@0: void MaybeLearnForStartup(const UriInfo &uri, const PRTime now); michael@0: michael@0: void LearnForToplevel(const UriInfo &uri); michael@0: void LearnForSubresource(const UriInfo &targetURI, const UriInfo &sourceURI); michael@0: void LearnForRedirect(const UriInfo &targetURI, const UriInfo &sourceURI); michael@0: void LearnForStartup(const UriInfo &uri); michael@0: michael@0: void ResetInternal(); michael@0: michael@0: void BeginTransaction() michael@0: { michael@0: mDB->BeginTransaction(); michael@0: } michael@0: michael@0: void CommitTransaction() michael@0: { michael@0: mDB->CommitTransaction(); michael@0: } michael@0: michael@0: int64_t GetDBFileSize(); michael@0: int64_t GetDBFileSizeAfterVacuum(); michael@0: void MaybeScheduleCleanup(); michael@0: void Cleanup(); michael@0: void CleanupOrigins(PRTime now); michael@0: void CleanupStartupPages(PRTime now); michael@0: int32_t GetSubresourceCount(); michael@0: michael@0: void VacuumDatabase(); michael@0: michael@0: // Observer-related stuff michael@0: nsresult InstallObserver(); michael@0: void RemoveObserver(); michael@0: michael@0: bool mInitialized; michael@0: michael@0: bool mEnabled; michael@0: bool mEnableHoverOnSSL; michael@0: michael@0: int mPageDegradationDay; michael@0: int mPageDegradationWeek; michael@0: int mPageDegradationMonth; michael@0: int mPageDegradationYear; michael@0: int mPageDegradationMax; michael@0: michael@0: int mSubresourceDegradationDay; michael@0: int mSubresourceDegradationWeek; michael@0: int mSubresourceDegradationMonth; michael@0: int mSubresourceDegradationYear; michael@0: int mSubresourceDegradationMax; michael@0: michael@0: int mPreconnectMinConfidence; michael@0: int mPreresolveMinConfidence; michael@0: int mRedirectLikelyConfidence; michael@0: michael@0: int32_t mMaxQueueSize; michael@0: michael@0: nsCOMPtr mIOThread; michael@0: michael@0: nsCOMPtr mSpeculativeService; michael@0: michael@0: nsCOMPtr mDBFile; michael@0: nsCOMPtr mStorageService; michael@0: nsCOMPtr mDB; michael@0: mozilla::storage::StatementCache mStatements; michael@0: michael@0: PRTime mStartupTime; michael@0: PRTime mLastStartupTime; michael@0: int32_t mStartupCount; michael@0: michael@0: nsCOMPtr mDnsService; michael@0: michael@0: int32_t mQueueSize; michael@0: mozilla::Mutex mQueueSizeLock; michael@0: michael@0: nsAutoPtr mAccumulators; michael@0: michael@0: nsRefPtr mDNSListener; michael@0: michael@0: nsCOMPtr mCommitTimer; michael@0: michael@0: #ifdef SEER_TESTS michael@0: friend class SeerPrepareForDnsTestEvent; michael@0: void PrepareForDnsTestInternal(int64_t timestamp, const nsACString &uri); michael@0: #endif michael@0: michael@0: bool mCleanupScheduled; michael@0: int32_t mMaxDBSize; michael@0: int32_t mPreservePercentage; michael@0: PRTime mLastCleanupTime; michael@0: }; michael@0: michael@0: } // ::mozilla::net michael@0: } // ::mozilla michael@0: michael@0: #endif // mozilla_net_Seer_h