mirror of
https://github.com/postgres/postgres.git
synced 2025-10-16 17:07:43 +03:00
Improve performance in freeing memory contexts
The single linked list of memory contexts could result in O(N^2) performance to free a set of contexts if they were not freed in reverse order of creation. In many cases the reverse order was used, but there were some significant exceptions that caused real- world performance problems. Rather than requiring all callers to care about the order in which contexts were freed, and hunting down and changing all existing cases where the wrong order was used, we add one pointer per memory context so that the implementation details are not so visible. Jan Wieck
This commit is contained in:
@@ -331,21 +331,16 @@ MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
|
||||
{
|
||||
MemoryContext parent = context->parent;
|
||||
|
||||
if (context == parent->firstchild)
|
||||
parent->firstchild = context->nextchild;
|
||||
if (context->prevchild != NULL)
|
||||
context->prevchild->nextchild = context->nextchild;
|
||||
else
|
||||
{
|
||||
MemoryContext child;
|
||||
|
||||
for (child = parent->firstchild; child; child = child->nextchild)
|
||||
{
|
||||
if (context == child->nextchild)
|
||||
{
|
||||
child->nextchild = context->nextchild;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Assert(parent->firstchild == context);
|
||||
parent->firstchild = context->nextchild;
|
||||
}
|
||||
|
||||
if (context->nextchild != NULL)
|
||||
context->nextchild->prevchild = context->prevchild;
|
||||
}
|
||||
|
||||
/* And relink */
|
||||
@@ -353,12 +348,16 @@ MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
|
||||
{
|
||||
AssertArg(MemoryContextIsValid(new_parent));
|
||||
context->parent = new_parent;
|
||||
context->prevchild = NULL;
|
||||
context->nextchild = new_parent->firstchild;
|
||||
if (new_parent->firstchild != NULL)
|
||||
new_parent->firstchild->prevchild = context;
|
||||
new_parent->firstchild = context;
|
||||
}
|
||||
else
|
||||
{
|
||||
context->parent = NULL;
|
||||
context->prevchild = NULL;
|
||||
context->nextchild = NULL;
|
||||
}
|
||||
}
|
||||
@@ -714,6 +713,7 @@ MemoryContextCreate(NodeTag tag, Size size,
|
||||
node->methods = methods;
|
||||
node->parent = NULL; /* for the moment */
|
||||
node->firstchild = NULL;
|
||||
node->prevchild = NULL;
|
||||
node->nextchild = NULL;
|
||||
node->isReset = true;
|
||||
node->name = ((char *) node) + size;
|
||||
@@ -728,6 +728,8 @@ MemoryContextCreate(NodeTag tag, Size size,
|
||||
{
|
||||
node->parent = parent;
|
||||
node->nextchild = parent->firstchild;
|
||||
if (parent->firstchild != NULL)
|
||||
parent->firstchild->prevchild = node;
|
||||
parent->firstchild = node;
|
||||
/* inherit allowInCritSection flag from parent */
|
||||
node->allowInCritSection = parent->allowInCritSection;
|
||||
|
Reference in New Issue
Block a user