summaryrefslogtreecommitdiff
path: root/src/backend/storage/page/bufpage.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/page/bufpage.c')
-rw-r--r--src/backend/storage/page/bufpage.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c
index 8299f550d6e..b246b0afeb8 100644
--- a/src/backend/storage/page/bufpage.c
+++ b/src/backend/storage/page/bufpage.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/page/bufpage.c,v 1.71 2007/02/21 20:02:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/page/bufpage.c,v 1.72 2007/03/02 00:48:44 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -39,6 +39,7 @@ PageInit(Page page, Size pageSize, Size specialSize)
/* Make sure all fields of page are zero, as well as unused space */
MemSet(p, 0, pageSize);
+ /* p->pd_flags = 0; done by above MemSet */
p->pd_lower = SizeOfPageHeaderData;
p->pd_upper = pageSize - specialSize;
p->pd_special = pageSize - specialSize;
@@ -73,6 +74,7 @@ PageHeaderIsValid(PageHeader page)
/* Check normal case */
if (PageGetPageSize(page) == BLCKSZ &&
PageGetPageLayoutVersion(page) == PG_PAGE_LAYOUT_VERSION &&
+ (page->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
page->pd_lower >= SizeOfPageHeaderData &&
page->pd_lower <= page->pd_upper &&
page->pd_upper <= page->pd_special &&
@@ -165,14 +167,27 @@ PageAddItem(Page page,
else
{
/* offsetNumber was not passed in, so find a free slot */
- /* look for "recyclable" (unused & deallocated) ItemId */
- for (offsetNumber = 1; offsetNumber < limit; offsetNumber++)
+ /* if no free slot, we'll put it at limit (1st open slot) */
+ if (PageHasFreeLinePointers(phdr))
+ {
+ /* look for "recyclable" (unused & deallocated) ItemId */
+ for (offsetNumber = 1; offsetNumber < limit; offsetNumber++)
+ {
+ itemId = PageGetItemId(phdr, offsetNumber);
+ if (!ItemIdIsUsed(itemId) && ItemIdGetLength(itemId) == 0)
+ break;
+ }
+ if (offsetNumber >= limit)
+ {
+ /* the hint is wrong, so reset it */
+ PageClearHasFreeLinePointers(phdr);
+ }
+ }
+ else
{
- itemId = PageGetItemId(phdr, offsetNumber);
- if (!ItemIdIsUsed(itemId) && ItemIdGetLength(itemId) == 0)
- break;
+ /* don't bother searching if hint says there's no free slot */
+ offsetNumber = limit;
}
- /* if no free slot, we'll put it at limit (1st open slot) */
}
if (offsetNumber > limit)
@@ -413,13 +428,19 @@ PageRepairFragmentation(Page page, OffsetNumber *unused)
pfree(itemidbase);
}
+ /* Set hint bit for PageAddItem */
+ if (nused < nline)
+ PageSetHasFreeLinePointers(page);
+ else
+ PageClearHasFreeLinePointers(page);
+
return (nline - nused);
}
/*
* PageGetFreeSpace
* Returns the size of the free (allocatable) space on a page,
- * deducted by the space needed for a new line pointer.
+ * reduced by the space needed for a new line pointer.
*/
Size
PageGetFreeSpace(Page page)