From 7a7ca7ea628137171de1092cadf8739220e65a9b Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Thu, 20 Feb 2014 14:48:28 -0500 Subject: [PATCH] Fix bugs. --- src/backend/utils/mmgr/freepage.c | 33 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/backend/utils/mmgr/freepage.c b/src/backend/utils/mmgr/freepage.c index 9aa7cce6df..802fb5cd71 100644 --- a/src/backend/utils/mmgr/freepage.c +++ b/src/backend/utils/mmgr/freepage.c @@ -393,9 +393,11 @@ FreePageBtreeGetRecycled(FreePageManager *fpm) Assert(victim != NULL); newhead = relptr_access(base, victim->next); - relptr_copy(newhead->prev, victim->prev); + if (newhead != NULL) + relptr_copy(newhead->prev, victim->prev); relptr_store(base, fpm->btree_recycle, newhead); Assert(fpm_pointer_is_page_aligned(base, victim)); + fpm->btree_recycle_count--; return (FreePageBtree *) victim; } @@ -406,6 +408,9 @@ static void FreePageBtreeInsertInternal(char *base, FreePageBtree *btp, Size index, Size first_page, FreePageBtree *child) { + Assert(btp->hdr.magic == FREE_PAGE_INTERNAL_MAGIC); + Assert(btp->hdr.nused <= FPM_ITEMS_PER_INTERNAL_PAGE); + Assert(index <= btp->hdr.nused); memmove(&btp->u.internal_key[index + 1], &btp->u.internal_key[index], sizeof(FreePageBtreeInternalKey) * (btp->hdr.nused - index)); btp->u.internal_key[index].first_page = first_page; @@ -420,6 +425,9 @@ static void FreePageBtreeInsertLeaf(FreePageBtree *btp, Size index, Size first_page, Size npages) { + Assert(btp->hdr.magic == FREE_PAGE_LEAF_MAGIC); + Assert(btp->hdr.nused <= FPM_ITEMS_PER_LEAF_PAGE); + Assert(index <= btp->hdr.nused); memmove(&btp->u.leaf_key[index + 1], &btp->u.leaf_key[index], sizeof(FreePageBtreeLeafKey) * (btp->hdr.nused - index)); btp->u.leaf_key[index].first_page = first_page; @@ -445,6 +453,7 @@ FreePageBtreeRecycle(FreePageManager *fpm, Size pageno) if (head != NULL) relptr_store(base, head->prev, span); relptr_store(base, fpm->btree_recycle, span); + fpm->btree_recycle_count++; } /* @@ -679,7 +688,7 @@ FreePageBtreeSearchInternal(FreePageBtree *btp, Size first_page) Size high = btp->hdr.nused; Assert(btp->hdr.magic == FREE_PAGE_INTERNAL_MAGIC); - Assert(high > 0 && high < FPM_ITEMS_PER_INTERNAL_PAGE); + Assert(high > 0 && high <= FPM_ITEMS_PER_INTERNAL_PAGE); while (low < high) { @@ -709,7 +718,7 @@ FreePageBtreeSearchLeaf(FreePageBtree *btp, Size first_page) Size high = btp->hdr.nused; Assert(btp->hdr.magic == FREE_PAGE_LEAF_MAGIC); - Assert(high > 0 && high < FPM_ITEMS_PER_LEAF_PAGE); + Assert(high > 0 && high <= FPM_ITEMS_PER_LEAF_PAGE); while (low < high) { @@ -796,7 +805,6 @@ FreePageManagerDumpBtree(FreePageManager *fpm, FreePageBtree *btp, int level, FreePageManagerDumpBtree(fpm, child, level + 1, buf); } } - appendStringInfo(buf, "\n"); } /* @@ -897,6 +905,7 @@ FreePageManagerGetInternal(FreePageManager *fpm, Size npages, Size *first_page) relptr_copy(fpm->freelist[f], victim->next); if (next != NULL) relptr_copy(next->prev, victim->prev); + victim_page = fpm_pointer_to_page(base, victim); /* * If we haven't initialized the btree yet, the victim must be the single @@ -905,7 +914,7 @@ FreePageManagerGetInternal(FreePageManager *fpm, Size npages, Size *first_page) */ if (relptr_is_null(fpm->btree_root)) { - Assert(fpm_pointer_to_page(base, victim) == fpm->singleton_first_page); + Assert(victim_page == fpm->singleton_first_page); Assert(victim->npages = fpm->singleton_npages); Assert(victim->npages >= npages); fpm->singleton_first_page += npages; @@ -1015,7 +1024,6 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages, FreePageBtreeSearchResult result; FreePageBtreeLeafKey *prevkey = NULL; FreePageBtreeLeafKey *nextkey = NULL; - Size index; /* We can store a single free span without initializing the btree. */ if (fpm->btree_depth == 0) @@ -1135,14 +1143,14 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages, Assert(first_page + npages == nextkey->first_page); newpages = (nextkey->first_page - first_page) + nextkey->npages; - /* Update key in place. */ - nextkey->first_page = first_page; - nextkey->npages = newpages; - /* Put span on correct free list. */ FreePagePopSpanLeader(fpm, nextkey->first_page); FreePagePushSpanLeader(fpm, first_page, newpages); + /* Update key in place. */ + nextkey->first_page = first_page; + nextkey->npages = newpages; + /* If reducing first key on page, ancestors might need adjustment. */ if (result.index_next == 0) FreePageBtreeAdjustAncestorKeys(fpm, result.page_next); @@ -1315,10 +1323,11 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages, /* Physically add the key to the page. */ Assert(result.page_next->hdr.nused < FPM_ITEMS_PER_LEAF_PAGE); - FreePageBtreeInsertLeaf(result.page_next, index, first_page, npages); + FreePageBtreeInsertLeaf(result.page_next, result.index_next, + first_page, npages); /* If new first key on page, ancestors might need adjustment. */ - if (index == 0) + if (result.index_next == 0) FreePageBtreeAdjustAncestorKeys(fpm, result.page_next); /* Put it on the free list. */ -- 2.39.5