--- a/netwerk/base/Predictor.cpp
+++ b/netwerk/base/Predictor.cpp
@@ -137,16 +137,18 @@ static const char PREDICTOR_MAX_RESOURCE
static const uint32_t PREDICTOR_MAX_RESOURCES_DEFAULT = 100;
// This is selected in concert with max-resources-per-entry to keep memory usage
// low-ish. The default of the combo of the two is ~50k
static const char PREDICTOR_MAX_URI_LENGTH_PREF[] =
"network.predictor.max-uri-length";
static const uint32_t PREDICTOR_MAX_URI_LENGTH_DEFAULT = 500;
+static const char PREDICTOR_DOING_TESTS_PREF[] = "network.predictor.doing-tests";
+
static const char PREDICTOR_CLEANED_UP_PREF[] = "network.predictor.cleaned-up";
// All these time values are in sec
static const uint32_t ONE_DAY = 86400U;
static const uint32_t ONE_WEEK = 7U * ONE_DAY;
static const uint32_t ONE_MONTH = 30U * ONE_DAY;
static const uint32_t ONE_YEAR = 365U * ONE_DAY;
@@ -350,16 +352,17 @@ Predictor::Predictor()
,mPrefetchMinConfidence(PREFETCH_MIN_DEFAULT)
,mPreconnectMinConfidence(PRECONNECT_MIN_DEFAULT)
,mPreresolveMinConfidence(PRERESOLVE_MIN_DEFAULT)
,mRedirectLikelyConfidence(REDIRECT_LIKELY_DEFAULT)
,mPrefetchForceValidFor(PREFETCH_FORCE_VALID_DEFAULT)
,mMaxResourcesPerEntry(PREDICTOR_MAX_RESOURCES_DEFAULT)
,mStartupCount(1)
,mMaxURILength(PREDICTOR_MAX_URI_LENGTH_DEFAULT)
+ ,mDoingTests(false)
{
MOZ_ASSERT(!sSelf, "multiple Predictor instances!");
sSelf = this;
}
Predictor::~Predictor()
{
if (mInitialized)
@@ -450,16 +453,18 @@ Predictor::InstallObserver()
PREDICTOR_MAX_RESOURCES_PREF,
PREDICTOR_MAX_RESOURCES_DEFAULT);
Preferences::AddBoolVarCache(&mCleanedUp, PREDICTOR_CLEANED_UP_PREF, false);
Preferences::AddUintVarCache(&mMaxURILength, PREDICTOR_MAX_URI_LENGTH_PREF,
PREDICTOR_MAX_URI_LENGTH_DEFAULT);
+ Preferences::AddBoolVarCache(&mDoingTests, PREDICTOR_DOING_TESTS_PREF, false);
+
if (!mCleanedUp) {
mCleanupTimer = do_CreateInstance("@mozilla.org/timer;1");
mCleanupTimer->Init(this, 60 * 1000, nsITimer::TYPE_ONE_SHOT);
}
return rv;
}
@@ -976,20 +981,20 @@ Predictor::PredictInternal(PredictorPred
if (isNew) {
// nothing else we can do here
PREDICTOR_LOG((" new entry"));
return rv;
}
switch (reason) {
case nsINetworkPredictor::PREDICT_LOAD:
- rv = PredictForPageload(entry, targetURI, stackCount, verifier);
+ rv = PredictForPageload(entry, targetURI, stackCount, fullUri, verifier);
break;
case nsINetworkPredictor::PREDICT_STARTUP:
- rv = PredictForStartup(entry, verifier);
+ rv = PredictForStartup(entry, fullUri, verifier);
break;
default:
PREDICTOR_LOG((" invalid reason"));
MOZ_ASSERT(false, "Got unexpected value for prediction reason");
}
return rv;
}
@@ -1022,17 +1027,17 @@ Predictor::PredictForLink(nsIURI *target
verifier->OnPredictPreconnect(targetURI);
}
}
// This is the driver for prediction based on a new pageload.
static const uint8_t MAX_PAGELOAD_DEPTH = 10;
bool
Predictor::PredictForPageload(nsICacheEntry *entry, nsIURI *targetURI,
- uint8_t stackCount,
+ uint8_t stackCount, bool fullUri,
nsINetworkPredictorVerifier *verifier)
{
MOZ_ASSERT(NS_IsMainThread());
PREDICTOR_LOG(("Predictor::PredictForPageload"));
if (stackCount > MAX_PAGELOAD_DEPTH) {
PREDICTOR_LOG((" exceeded recursion depth!"));
@@ -1068,33 +1073,33 @@ Predictor::PredictForPageload(nsICacheEn
nsICacheStorage::OPEN_SECRETLY |
nsICacheStorage::OPEN_PRIORITY |
nsICacheStorage::CHECK_MULTITHREADED;
mCacheDiskStorage->AsyncOpenURI(redirectURI, EmptyCString(), openFlags,
redirectAction);
return RunPredictions(nullptr, verifier);
}
- CalculatePredictions(entry, targetURI, lastLoad, loadCount, globalDegradation);
+ CalculatePredictions(entry, targetURI, lastLoad, loadCount, globalDegradation, fullUri);
return RunPredictions(targetURI, verifier);
}
// This is the driver for predicting at browser startup time based on pages that
// have previously been loaded close to startup.
bool
-Predictor::PredictForStartup(nsICacheEntry *entry,
+Predictor::PredictForStartup(nsICacheEntry *entry, bool fullUri,
nsINetworkPredictorVerifier *verifier)
{
MOZ_ASSERT(NS_IsMainThread());
PREDICTOR_LOG(("Predictor::PredictForStartup"));
int32_t globalDegradation = CalculateGlobalDegradation(mLastStartupTime);
CalculatePredictions(entry, nullptr, mLastStartupTime, mStartupCount,
- globalDegradation);
+ globalDegradation, fullUri);
return RunPredictions(nullptr, verifier);
}
// This calculates how much to degrade our confidence in our data based on
// the last time this top-level resource was loaded. This "global degradation"
// applies to *all* subresources we have associated with the top-level
// resource. This will be in addition to any reduction in confidence we have
// associated with a particular subresource.
@@ -1237,17 +1242,17 @@ Predictor::SanitizePrefs()
} else if (mPrefetchRollingLoadCount > kMaxPrefetchRollingLoadCount) {
mPrefetchRollingLoadCount = kMaxPrefetchRollingLoadCount;
}
}
void
Predictor::CalculatePredictions(nsICacheEntry *entry, nsIURI *referrer,
uint32_t lastLoad, uint32_t loadCount,
- int32_t globalDegradation)
+ int32_t globalDegradation, bool fullUri)
{
MOZ_ASSERT(NS_IsMainThread());
SanitizePrefs();
// Since the visitor gets called under a cache lock, all we do there is get
// copies of the keys/values we care about, and then do the real work here
entry->VisitMetaData(this);
@@ -1265,19 +1270,25 @@ Predictor::CalculatePredictions(nsICache
if (!ParseMetaDataEntry(key, value, getter_AddRefs(uri), hitCount, lastHit, flags)) {
// This failed, get rid of it so we don't waste space
entry->SetMetaDataElement(key, nullptr);
continue;
}
int32_t confidence = CalculateConfidence(hitCount, loadCount, lastHit,
lastLoad, globalDegradation);
- UpdateRollingLoadCount(entry, flags, key, hitCount, lastHit);
+ if (fullUri) {
+ UpdateRollingLoadCount(entry, flags, key, hitCount, lastHit);
+ }
PREDICTOR_LOG(("CalculatePredictions key=%s value=%s confidence=%d", key, value, confidence));
- if (!referrer) {
+ if (!fullUri) {
+ // Not full URI - don't prefetch! No sense in it!
+ PREDICTOR_LOG((" forcing non-cacheability - not full URI"));
+ flags &= ~FLAG_PREFETCHABLE;
+ } else if (!referrer) {
// No referrer means we can't prefetch, so pretend it's non-cacheable,
// no matter what.
PREDICTOR_LOG((" forcing non-cacheability - no referrer"));
flags &= ~FLAG_PREFETCHABLE;
} else {
uint32_t expectedRollingLoadCount = (1 << mPrefetchRollingLoadCount) - 1;
expectedRollingLoadCount <<= kRollingLoadOffset;
if ((flags & expectedRollingLoadCount) != expectedRollingLoadCount) {
@@ -1640,17 +1651,17 @@ Predictor::LearnInternal(PredictorLearnR
switch (reason) {
case nsINetworkPredictor::LEARN_LOAD_TOPLEVEL:
// This case only exists to be used during tests - code outside the
// predictor tests should NEVER call Learn with LEARN_LOAD_TOPLEVEL.
// The predictor xpcshell test needs this branch, however, because we
// have no real page loads in xpcshell, and this is how we fake it up
// so that all the work that normally happens behind the scenes in a
// page load can be done for testing purposes.
- if (fullUri) {
+ if (fullUri && mDoingTests) {
PREDICTOR_LOG((" WARNING - updating rolling load count. "
"If you see this outside tests, you did it wrong"));
SanitizePrefs();
// Since the visitor gets called under a cache lock, all we do there is get
// copies of the keys/values we care about, and then do the real work here
entry->VisitMetaData(this);
nsTArray<nsCString> keysToOperateOn, valuesToOperateOn;
--- a/netwerk/base/Predictor.h
+++ b/netwerk/base/Predictor.h
@@ -260,22 +260,24 @@ private:
nsINetworkPredictorVerifier *verifier);
// Used when predicting because a page is being loaded (which may include
// being the target of a redirect). All arguments are the same as for
// PredictInternal. Returns true if any predictions were queued up.
bool PredictForPageload(nsICacheEntry *entry,
nsIURI *targetURI,
uint8_t stackCount,
+ bool fullUri,
nsINetworkPredictorVerifier *verifier);
// Used when predicting pages that will be used near browser startup. All
// arguments are the same as for PredictInternal. Returns true if any
// predictions were queued up.
bool PredictForStartup(nsICacheEntry *entry,
+ bool fullUri,
nsINetworkPredictorVerifier *verifier);
// Utilities related to prediction
// Used to update our rolling load count (how many of the last n loads was a
// partular resource loaded on?)
// * entry - cache entry of page we're loading
// * flags - value that contains our rolling count as the top 20 bits (but
@@ -311,19 +313,20 @@ private:
// Used to calculate all confidence values for all resources associated with a
// page.
// * entry - the cache entry with all necessary information about this page
// * referrer - the URI that we are loading (may be null)
// * lastLoad - timestamp of the last time this page was loaded
// * loadCount - number of times this page has been loaded
// * gloablDegradation - value calculated by CalculateGlobalDegradation for
// this page
+ // * fullUri - whether we're predicting for a full URI or origin-only
void CalculatePredictions(nsICacheEntry *entry, nsIURI *referrer,
uint32_t lastLoad, uint32_t loadCount,
- int32_t globalDegradation);
+ int32_t globalDegradation, bool fullUri);
// Used to prepare any necessary prediction for a resource on a page
// * confidence - value calculated by CalculateConfidence for this resource
// * flags - the flags taken from the resource
// * uri - the URI of the resource
void SetupPrediction(int32_t confidence, uint32_t flags, nsIURI *uri);
// Used to kick off a prefetch from RunPredictions if necessary
@@ -461,15 +464,17 @@ private:
nsCOMPtr<nsIDNSService> mDnsService;
RefPtr<DNSListener> mDNSListener;
nsTArray<nsCOMPtr<nsIURI>> mPrefetches;
nsTArray<nsCOMPtr<nsIURI>> mPreconnects;
nsTArray<nsCOMPtr<nsIURI>> mPreresolves;
+ bool mDoingTests;
+
static Predictor *sSelf;
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_Predictor_h