Bug 1350770: Cache the most recent nsGenConNode to speed up future insertions. r=xidorn
This commit is contained in:
@@ -19,6 +19,7 @@ nsGenConList::Clear()
|
|||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
mSize = 0;
|
mSize = 0;
|
||||||
|
mLastInserted = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -41,6 +42,9 @@ nsGenConList::DestroyNodesFor(nsIFrame* aFrame)
|
|||||||
node = nextNode;
|
node = nextNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Modification of the list invalidates the cached pointer.
|
||||||
|
mLastInserted = nullptr;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +112,11 @@ nsGenConList::Insert(nsGenConNode* aNode)
|
|||||||
// Check for append.
|
// Check for append.
|
||||||
if (mList.isEmpty() || NodeAfter(aNode, mList.getLast())) {
|
if (mList.isEmpty() || NodeAfter(aNode, mList.getLast())) {
|
||||||
mList.insertBack(aNode);
|
mList.insertBack(aNode);
|
||||||
|
} else if (mLastInserted && mLastInserted != mList.getLast() &&
|
||||||
|
NodeAfter(aNode, mLastInserted) &&
|
||||||
|
NodeAfter(Next(mLastInserted), aNode)) {
|
||||||
|
// Fast path for inserting many consecutive nodes in one place
|
||||||
|
mLastInserted->setNext(aNode);
|
||||||
} else {
|
} else {
|
||||||
// Binary search.
|
// Binary search.
|
||||||
|
|
||||||
@@ -142,6 +151,8 @@ nsGenConList::Insert(nsGenConNode* aNode)
|
|||||||
}
|
}
|
||||||
++mSize;
|
++mSize;
|
||||||
|
|
||||||
|
mLastInserted = aNode;
|
||||||
|
|
||||||
// Set the mapping only if it is the first node of the frame.
|
// Set the mapping only if it is the first node of the frame.
|
||||||
// The DEBUG blocks below are for ensuring the invariant required by
|
// The DEBUG blocks below are for ensuring the invariant required by
|
||||||
// nsGenConList::DestroyNodesFor. See comment there.
|
// nsGenConList::DestroyNodesFor. See comment there.
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ protected:
|
|||||||
uint32_t mSize;
|
uint32_t mSize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsGenConList() : mSize(0) {}
|
nsGenConList() : mSize(0), mLastInserted(nullptr) {}
|
||||||
~nsGenConList() { Clear(); }
|
~nsGenConList() { Clear(); }
|
||||||
void Clear();
|
void Clear();
|
||||||
static nsGenConNode* Next(nsGenConNode* aNode) {
|
static nsGenConNode* Next(nsGenConNode* aNode) {
|
||||||
@@ -127,6 +127,10 @@ private:
|
|||||||
|
|
||||||
// Map from frame to the first nsGenConNode of it in the list.
|
// Map from frame to the first nsGenConNode of it in the list.
|
||||||
nsDataHashtable<nsPtrHashKey<nsIFrame>, nsGenConNode*> mNodes;
|
nsDataHashtable<nsPtrHashKey<nsIFrame>, nsGenConNode*> mNodes;
|
||||||
|
|
||||||
|
// A weak pointer to the node most recently inserted, used to avoid repeated
|
||||||
|
// list traversals in Insert().
|
||||||
|
nsGenConNode* mLastInserted;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsGenConList_h___ */
|
#endif /* nsGenConList_h___ */
|
||||||
|
|||||||
Reference in New Issue
Block a user