diff options
Diffstat (limited to 'src/backend/utils/mmgr')
-rw-r--r-- | src/backend/utils/mmgr/README | 11 | ||||
-rw-r--r-- | src/backend/utils/mmgr/mcxt.c | 46 |
2 files changed, 30 insertions, 27 deletions
diff --git a/src/backend/utils/mmgr/README b/src/backend/utils/mmgr/README index 45e610dd061..4ebb78e4eb0 100644 --- a/src/backend/utils/mmgr/README +++ b/src/backend/utils/mmgr/README @@ -125,9 +125,14 @@ lifetimes that only partially overlap can be handled by allocating from different trees of the context forest (there are some examples in the next section). -For convenience we will also want operations like "reset/delete all -children of a given context, but don't reset or delete that context -itself". +Actually, it turns out that resetting a given context should almost +always imply deleting (not just resetting) any child contexts it has. +So MemoryContextReset() means that, and if you really do want a tree of +empty contexts you need to call MemoryContextResetOnly() plus +MemoryContextResetChildren(). + +For convenience we also provide operations like "reset/delete all children +of a given context, but don't reset or delete that context itself". Globally Known Contexts diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index 72a32abdddb..e2fbfd420b6 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -132,11 +132,8 @@ MemoryContextInit(void) /* * MemoryContextReset - * Release all space allocated within a context and its descendants, - * but don't delete the contexts themselves. - * - * The type-specific reset routine handles the context itself, but we - * have to do the recursion for the children. + * Release all space allocated within a context and delete all its + * descendant contexts (but not the named context itself). */ void MemoryContextReset(MemoryContext context) @@ -145,7 +142,22 @@ MemoryContextReset(MemoryContext context) /* save a function call in common case where there are no children */ if (context->firstchild != NULL) - MemoryContextResetChildren(context); + MemoryContextDeleteChildren(context); + + /* save a function call if no pallocs since startup or last reset */ + if (!context->isReset) + MemoryContextResetOnly(context); +} + +/* + * MemoryContextResetOnly + * Release all space allocated within a context. + * Nothing is done to the context's descendant contexts. + */ +void +MemoryContextResetOnly(MemoryContext context) +{ + AssertArg(MemoryContextIsValid(context)); /* Nothing to do if no pallocs since startup or last reset */ if (!context->isReset) @@ -172,7 +184,10 @@ MemoryContextResetChildren(MemoryContext context) AssertArg(MemoryContextIsValid(context)); for (child = context->firstchild; child != NULL; child = child->nextchild) - MemoryContextReset(child); + { + MemoryContextResetChildren(child); + MemoryContextResetOnly(child); + } } /* @@ -235,23 +250,6 @@ MemoryContextDeleteChildren(MemoryContext context) } /* - * MemoryContextResetAndDeleteChildren - * Release all space allocated within a context and delete all - * its descendants. - * - * This is a common combination case where we want to preserve the - * specific context but get rid of absolutely everything under it. - */ -void -MemoryContextResetAndDeleteChildren(MemoryContext context) -{ - AssertArg(MemoryContextIsValid(context)); - - MemoryContextDeleteChildren(context); - MemoryContextReset(context); -} - -/* * MemoryContextRegisterResetCallback * Register a function to be called before next context reset/delete. * Such callbacks will be called in reverse order of registration. |