зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1380154 - Part 3: Cache most recently used eTLD entries. r=njn, r=jduell
This adds a most recently used (MRU) cache for the most common base domain requests (aAddtionalParts == 1). With a table size of 31 I saw 8777 hits and 22 misses when loading twitter, youtube, and techcrunch. In stress testing this provided a 75% reduction in run time. MozReview-Commit-ID: 3JgCwIZagMs
This commit is contained in:
Родитель
f5b13e0ecb
Коммит
7301b9928c
|
@ -9,8 +9,10 @@
|
||||||
// http://wiki.mozilla.org/Gecko:Effective_TLD_Service
|
// http://wiki.mozilla.org/Gecko:Effective_TLD_Service
|
||||||
|
|
||||||
#include "mozilla/ArrayUtils.h"
|
#include "mozilla/ArrayUtils.h"
|
||||||
|
#include "mozilla/HashFunctions.h"
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
|
|
||||||
|
#include "MainThreadUtils.h"
|
||||||
#include "nsEffectiveTLDService.h"
|
#include "nsEffectiveTLDService.h"
|
||||||
#include "nsIIDNService.h"
|
#include "nsIIDNService.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
|
@ -210,6 +212,20 @@ nsEffectiveTLDService::GetBaseDomainInternal(nsCString &aHostname,
|
||||||
if (result == PR_SUCCESS)
|
if (result == PR_SUCCESS)
|
||||||
return NS_ERROR_HOST_IS_IP_ADDRESS;
|
return NS_ERROR_HOST_IS_IP_ADDRESS;
|
||||||
|
|
||||||
|
// Lookup in the cache if this is a normal query.
|
||||||
|
TLDCacheEntry* entry = nullptr;
|
||||||
|
if (aAdditionalParts == 1) {
|
||||||
|
if (LookupForAdd(aHostname, &entry)) {
|
||||||
|
// There was a match, just return the cached value.
|
||||||
|
aBaseDomain = entry->mBaseDomain;
|
||||||
|
if (trailingDot) {
|
||||||
|
aBaseDomain.Append('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Walk up the domain tree, most specific to least specific,
|
// Walk up the domain tree, most specific to least specific,
|
||||||
// looking for matches at each level. Note that a given level may
|
// looking for matches at each level. Note that a given level may
|
||||||
// have multiple attributes (e.g. IsWild() and IsNormal()).
|
// have multiple attributes (e.g. IsWild() and IsNormal()).
|
||||||
|
@ -290,6 +306,13 @@ nsEffectiveTLDService::GetBaseDomainInternal(nsCString &aHostname,
|
||||||
return NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS;
|
return NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS;
|
||||||
|
|
||||||
aBaseDomain = Substring(iter, end);
|
aBaseDomain = Substring(iter, end);
|
||||||
|
|
||||||
|
// Update the MRU table if in use.
|
||||||
|
if (entry) {
|
||||||
|
entry->mHost = aHostname;
|
||||||
|
entry->mBaseDomain = aBaseDomain;
|
||||||
|
}
|
||||||
|
|
||||||
// add on the trailing dot, if applicable
|
// add on the trailing dot, if applicable
|
||||||
if (trailingDot)
|
if (trailingDot)
|
||||||
aBaseDomain.Append('.');
|
aBaseDomain.Append('.');
|
||||||
|
@ -312,3 +335,13 @@ nsEffectiveTLDService::NormalizeHostname(nsCString &aHostname)
|
||||||
ToLowerCase(aHostname);
|
ToLowerCase(aHostname);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsEffectiveTLDService::LookupForAdd(const nsACString& aHost, TLDCacheEntry** aEntry)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
const uint32_t hash = HashString(aHost.BeginReading(), aHost.Length());
|
||||||
|
*aEntry = &mMruTable[hash % kTableSize];
|
||||||
|
return (*aEntry)->mHost == aHost;
|
||||||
|
}
|
||||||
|
|
|
@ -37,7 +37,40 @@ private:
|
||||||
~nsEffectiveTLDService();
|
~nsEffectiveTLDService();
|
||||||
|
|
||||||
nsCOMPtr<nsIIDNService> mIDNService;
|
nsCOMPtr<nsIIDNService> mIDNService;
|
||||||
|
|
||||||
|
// The DAFSA provides a compact encoding of the rather large eTLD list.
|
||||||
mozilla::Dafsa mGraph;
|
mozilla::Dafsa mGraph;
|
||||||
|
|
||||||
|
struct TLDCacheEntry
|
||||||
|
{
|
||||||
|
nsCString mHost;
|
||||||
|
nsCString mBaseDomain;
|
||||||
|
};
|
||||||
|
|
||||||
|
// We use a small most recently used cache to compensate for DAFSA lookups
|
||||||
|
// being slightly slower than a binary search on a larger table of strings.
|
||||||
|
//
|
||||||
|
// We first check the cache for a matching result and avoid a DAFSA lookup
|
||||||
|
// if a match is found. Otherwise we lookup the domain in the DAFSA and then
|
||||||
|
// cache the result. During standard browsing the same domains are repeatedly
|
||||||
|
// fed into |GetBaseDomainInternal| so this ends up being an effective
|
||||||
|
// mitigation getting about a 99% hit rate with four tabs open.
|
||||||
|
//
|
||||||
|
// A size of 31 is used rather than a more logical power-of-two such as 32
|
||||||
|
// since it is a prime number and provides fewer collisions when when used
|
||||||
|
// with our hash algorithms.
|
||||||
|
static const uint32_t kTableSize = 31;
|
||||||
|
TLDCacheEntry mMruTable[kTableSize];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a lookup on the MRU table and provides a pointer to the hash
|
||||||
|
* entry that matched or should be used for adding this host.
|
||||||
|
*
|
||||||
|
* @param aHost The host to lookup.
|
||||||
|
* @param aEntry Out param, the entry in the MRU table to use.
|
||||||
|
* @return True if a match was found, false if there was a miss.
|
||||||
|
*/
|
||||||
|
inline bool LookupForAdd(const nsACString& aHost, TLDCacheEntry** aEntry);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EffectiveTLDService_h
|
#endif // EffectiveTLDService_h
|
||||||
|
|
Загрузка…
Ссылка в новой задаче