Bug 702217 - Avoid double allocation in UrlClassifier. Handle OOM conditions. r=dcamp

This commit is contained in:
Gian-Carlo Pascutto
2012-01-10 17:09:32 +01:00
parent a21decbb85
commit 2bb82902d1
7 changed files with 119 additions and 79 deletions

View File

@@ -189,7 +189,7 @@ nsUrlClassifierPrefixSet::InitKey()
NS_IMETHODIMP
nsUrlClassifierPrefixSet::SetPrefixes(const PRUint32 * aArray, PRUint32 aLength)
{
{
if (aLength <= 0) {
MutexAutoLock lock(mPrefixSetLock);
if (mHasPrefixes) {
LOG(("Clearing PrefixSet"));
@@ -198,61 +198,72 @@ nsUrlClassifierPrefixSet::SetPrefixes(const PRUint32 * aArray, PRUint32 aLength)
mIndexStarts.Clear();
mHasPrefixes = false;
}
}
if (aLength > 0) {
// Ensure they are sorted before adding
nsTArray<PRUint32> prefixes;
prefixes.AppendElements(aArray, aLength);
prefixes.Sort();
AddPrefixes(prefixes.Elements(), prefixes.Length());
} else {
return MakePrefixSet(aArray, aLength);
}
return NS_OK;
}
NS_IMETHODIMP
nsUrlClassifierPrefixSet::AddPrefixes(const PRUint32 * prefixes, PRUint32 aLength)
nsresult
nsUrlClassifierPrefixSet::MakePrefixSet(const PRUint32 * prefixes, PRUint32 aLength)
{
if (aLength == 0) {
return NS_OK;
}
nsTArray<PRUint32> mNewIndexPrefixes(mIndexPrefixes);
nsTArray<PRUint32> mNewIndexStarts(mIndexStarts);
nsTArray<PRUint16> mNewDeltas(mDeltas);
#ifdef DEBUG
for (PRUint32 i = 1; i < aLength; i++) {
MOZ_ASSERT(prefixes[i] >= prefixes[i-1]);
}
#endif
mNewIndexPrefixes.AppendElement(prefixes[0]);
mNewIndexStarts.AppendElement(mNewDeltas.Length());
FallibleTArray<PRUint32> newIndexPrefixes;
FallibleTArray<PRUint32> newIndexStarts;
FallibleTArray<PRUint16> newDeltas;
if (!newIndexPrefixes.AppendElement(prefixes[0])) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (!newIndexStarts.AppendElement(newDeltas.Length())) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRUint32 numOfDeltas = 0;
PRUint32 currentItem = prefixes[0];
for (PRUint32 i = 1; i < aLength; i++) {
if ((numOfDeltas >= DELTAS_LIMIT) ||
(prefixes[i] - currentItem >= MAX_INDEX_DIFF)) {
mNewIndexStarts.AppendElement(mNewDeltas.Length());
mNewIndexPrefixes.AppendElement(prefixes[i]);
if (!newIndexStarts.AppendElement(newDeltas.Length())) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (!newIndexPrefixes.AppendElement(prefixes[i])) {
return NS_ERROR_OUT_OF_MEMORY;
}
numOfDeltas = 0;
} else {
PRUint16 delta = prefixes[i] - currentItem;
mNewDeltas.AppendElement(delta);
if (!newDeltas.AppendElement(delta)) {
return NS_ERROR_OUT_OF_MEMORY;
}
numOfDeltas++;
}
currentItem = prefixes[i];
}
mNewIndexPrefixes.Compact();
mNewIndexStarts.Compact();
mNewDeltas.Compact();
newIndexPrefixes.Compact();
newIndexStarts.Compact();
newDeltas.Compact();
LOG(("Total number of indices: %d", mNewIndexPrefixes.Length()));
LOG(("Total number of deltas: %d", mNewDeltas.Length()));
LOG(("Total number of indices: %d", newIndexPrefixes.Length()));
LOG(("Total number of deltas: %d", newDeltas.Length()));
MutexAutoLock lock(mPrefixSetLock);
// This just swaps some pointers
mIndexPrefixes.SwapElements(mNewIndexPrefixes);
mIndexStarts.SwapElements(mNewIndexStarts);
mDeltas.SwapElements(mNewDeltas);
mIndexPrefixes.SwapElements(newIndexPrefixes);
mIndexStarts.SwapElements(newIndexStarts);
mDeltas.SwapElements(newDeltas);
mHasPrefixes = true;
mSetIsReady.NotifyAll();
@@ -278,7 +289,7 @@ PRUint32 nsUrlClassifierPrefixSet::BinSearch(PRUint32 start,
return end;
}
NS_IMETHODIMP
nsresult
nsUrlClassifierPrefixSet::Contains(PRUint32 aPrefix, bool * aFound)
{
mPrefixSetLock.AssertCurrentThreadOwns();