diff -rc postgresql-8.0.0.orig/src/backend/access/heap/heapam.c postgresql-8.0.0.pctfree/src/backend/access/heap/heapam.c *** postgresql-8.0.0.orig/src/backend/access/heap/heapam.c 2005-01-01 06:59:16.000000000 +0900 --- postgresql-8.0.0.pctfree/src/backend/access/heap/heapam.c 2005-08-20 23:20:45.017901208 +0900 *************** *** 1151,1157 **** heap_tuple_toast_attrs(relation, tup, NULL); /* Find buffer to insert this tuple into */ ! buffer = RelationGetBufferForTuple(relation, tup->t_len, InvalidBuffer); /* NO EREPORT(ERROR) from here till changes are logged */ START_CRIT_SECTION(); --- 1151,1160 ---- heap_tuple_toast_attrs(relation, tup, NULL); /* Find buffer to insert this tuple into */ ! buffer = RelationGetBufferForTuple(relation, ! tup->t_len, ! InvalidBuffer, ! true); /* NO EREPORT(ERROR) from here till changes are logged */ START_CRIT_SECTION(); *************** *** 1671,1678 **** if (newtupsize > pagefree) { /* Assume there's no chance to put newtup on same page. */ ! newbuf = RelationGetBufferForTuple(relation, newtup->t_len, ! buffer); } else { --- 1674,1683 ---- if (newtupsize > pagefree) { /* Assume there's no chance to put newtup on same page. */ ! newbuf = RelationGetBufferForTuple(relation, ! newtup->t_len, ! buffer, ! false); } else { *************** *** 1688,1695 **** * should seldom be taken. */ LockBuffer(buffer, BUFFER_LOCK_UNLOCK); ! newbuf = RelationGetBufferForTuple(relation, newtup->t_len, ! buffer); } else { --- 1693,1702 ---- * should seldom be taken. */ LockBuffer(buffer, BUFFER_LOCK_UNLOCK); ! newbuf = RelationGetBufferForTuple(relation, ! newtup->t_len, ! buffer, ! false); } else { diff -rc postgresql-8.0.0.orig/src/backend/access/heap/hio.c postgresql-8.0.0.pctfree/src/backend/access/heap/hio.c *** postgresql-8.0.0.orig/src/backend/access/heap/hio.c 2005-01-01 06:59:16.000000000 +0900 --- postgresql-8.0.0.pctfree/src/backend/access/heap/hio.c 2005-08-20 23:35:44.986085248 +0900 *************** *** 89,95 **** */ Buffer RelationGetBufferForTuple(Relation relation, Size len, ! Buffer otherBuffer) { Buffer buffer = InvalidBuffer; Page pageHeader; --- 89,95 ---- */ Buffer RelationGetBufferForTuple(Relation relation, Size len, ! Buffer otherBuffer, bool forInsert) { Buffer buffer = InvalidBuffer; Page pageHeader; *************** *** 136,142 **** * We have no cached target page, so ask the FSM for an initial * target. */ ! targetBlock = GetPageWithFreeSpace(&relation->rd_node, len); /* * If the FSM knows nothing of the rel, try the last page before --- 136,142 ---- * We have no cached target page, so ask the FSM for an initial * target. */ ! targetBlock = GetPageWithFreeSpace(&relation->rd_node, len, forInsert); /* * If the FSM knows nothing of the rel, try the last page before *************** *** 192,198 **** */ pageHeader = (Page) BufferGetPage(buffer); pageFreeSpace = PageGetFreeSpace(pageHeader); ! if (len <= pageFreeSpace) { /* use this page as future insert target, too */ relation->rd_targblock = targetBlock; --- 192,198 ---- */ pageHeader = (Page) BufferGetPage(buffer); pageFreeSpace = PageGetFreeSpace(pageHeader); ! if ((forInsert ? (len+1024) : len) <= pageFreeSpace) { /* use this page as future insert target, too */ relation->rd_targblock = targetBlock; *************** *** 221,227 **** targetBlock = RecordAndGetPageWithFreeSpace(&relation->rd_node, targetBlock, pageFreeSpace, ! len); } /* --- 221,228 ---- targetBlock = RecordAndGetPageWithFreeSpace(&relation->rd_node, targetBlock, pageFreeSpace, ! len, ! forInsert); } /* diff -rc postgresql-8.0.0.orig/src/backend/storage/freespace/freespace.c postgresql-8.0.0.pctfree/src/backend/storage/freespace/freespace.c *** postgresql-8.0.0.orig/src/backend/storage/freespace/freespace.c 2005-01-01 07:00:54.000000000 +0900 --- postgresql-8.0.0.pctfree/src/backend/storage/freespace/freespace.c 2005-08-20 23:18:21.413732360 +0900 *************** *** 229,235 **** static void unlink_fsm_rel_usage(FSMRelation *fsmrel); static void link_fsm_rel_storage(FSMRelation *fsmrel); static void unlink_fsm_rel_storage(FSMRelation *fsmrel); ! static BlockNumber find_free_space(FSMRelation *fsmrel, Size spaceNeeded); static BlockNumber find_index_free_space(FSMRelation *fsmrel); static void fsm_record_free_space(FSMRelation *fsmrel, BlockNumber page, Size spaceAvail); --- 229,237 ---- static void unlink_fsm_rel_usage(FSMRelation *fsmrel); static void link_fsm_rel_storage(FSMRelation *fsmrel); static void unlink_fsm_rel_storage(FSMRelation *fsmrel); ! static BlockNumber find_free_space(FSMRelation *fsmrel, ! Size spaceNeeded, ! bool forInsert); static BlockNumber find_index_free_space(FSMRelation *fsmrel); static void fsm_record_free_space(FSMRelation *fsmrel, BlockNumber page, Size spaceAvail); *************** *** 359,365 **** * extend the relation. */ BlockNumber ! GetPageWithFreeSpace(RelFileNode *rel, Size spaceNeeded) { FSMRelation *fsmrel; BlockNumber freepage; --- 361,367 ---- * extend the relation. */ BlockNumber ! GetPageWithFreeSpace(RelFileNode *rel, Size spaceNeeded, bool forInsert) { FSMRelation *fsmrel; BlockNumber freepage; *************** *** 384,390 **** cur_avg += ((int) spaceNeeded - cur_avg) / 32; fsmrel->avgRequest = (Size) cur_avg; } ! freepage = find_free_space(fsmrel, spaceNeeded); LWLockRelease(FreeSpaceLock); return freepage; } --- 386,392 ---- cur_avg += ((int) spaceNeeded - cur_avg) / 32; fsmrel->avgRequest = (Size) cur_avg; } ! freepage = find_free_space(fsmrel, spaceNeeded, forInsert); LWLockRelease(FreeSpaceLock); return freepage; } *************** *** 399,405 **** RecordAndGetPageWithFreeSpace(RelFileNode *rel, BlockNumber oldPage, Size oldSpaceAvail, ! Size spaceNeeded) { FSMRelation *fsmrel; BlockNumber freepage; --- 401,408 ---- RecordAndGetPageWithFreeSpace(RelFileNode *rel, BlockNumber oldPage, Size oldSpaceAvail, ! Size spaceNeeded, ! bool forInsert) { FSMRelation *fsmrel; BlockNumber freepage; *************** *** 429,435 **** fsmrel->avgRequest = (Size) cur_avg; } /* Do the Get */ ! freepage = find_free_space(fsmrel, spaceNeeded); LWLockRelease(FreeSpaceLock); return freepage; } --- 432,438 ---- fsmrel->avgRequest = (Size) cur_avg; } /* Do the Get */ ! freepage = find_free_space(fsmrel, spaceNeeded, forInsert); LWLockRelease(FreeSpaceLock); return freepage; } *************** *** 1204,1210 **** * if no success. */ static BlockNumber ! find_free_space(FSMRelation *fsmrel, Size spaceNeeded) { FSMPageData *info; int pagesToCheck, /* outer loop counter */ --- 1207,1213 ---- * if no success. */ static BlockNumber ! find_free_space(FSMRelation *fsmrel, Size spaceNeeded, bool forInsert) { FSMPageData *info; int pagesToCheck, /* outer loop counter */ *************** *** 1225,1231 **** Size spaceAvail = FSMPageGetSpace(page); /* Check this page */ ! if (spaceAvail >= spaceNeeded) { /* * Found what we want --- adjust the entry, and update --- 1228,1234 ---- Size spaceAvail = FSMPageGetSpace(page); /* Check this page */ ! if (spaceAvail >= (forInsert ? (spaceNeeded + 1024) : spaceNeeded) ) { /* * Found what we want --- adjust the entry, and update diff -rc postgresql-8.0.0.orig/src/include/access/hio.h postgresql-8.0.0.pctfree/src/include/access/hio.h *** postgresql-8.0.0.orig/src/include/access/hio.h 2005-01-01 07:03:21.000000000 +0900 --- postgresql-8.0.0.pctfree/src/include/access/hio.h 2005-08-20 23:13:20.267513544 +0900 *************** *** 19,24 **** extern void RelationPutHeapTuple(Relation relation, Buffer buffer, HeapTuple tuple); extern Buffer RelationGetBufferForTuple(Relation relation, Size len, ! Buffer otherBuffer); #endif /* HIO_H */ --- 19,24 ---- extern void RelationPutHeapTuple(Relation relation, Buffer buffer, HeapTuple tuple); extern Buffer RelationGetBufferForTuple(Relation relation, Size len, ! Buffer otherBuffer, bool forInsert); #endif /* HIO_H */ diff -rc postgresql-8.0.0.orig/src/include/storage/freespace.h postgresql-8.0.0.pctfree/src/include/storage/freespace.h *** postgresql-8.0.0.orig/src/include/storage/freespace.h 2005-01-01 07:03:42.000000000 +0900 --- postgresql-8.0.0.pctfree/src/include/storage/freespace.h 2005-08-20 23:18:46.661894056 +0900 *************** *** 39,49 **** extern void InitFreeSpaceMap(void); extern int FreeSpaceShmemSize(void); ! extern BlockNumber GetPageWithFreeSpace(RelFileNode *rel, Size spaceNeeded); extern BlockNumber RecordAndGetPageWithFreeSpace(RelFileNode *rel, BlockNumber oldPage, Size oldSpaceAvail, ! Size spaceNeeded); extern Size GetAvgFSMRequestSize(RelFileNode *rel); extern void RecordRelationFreeSpace(RelFileNode *rel, int nPages, --- 39,52 ---- extern void InitFreeSpaceMap(void); extern int FreeSpaceShmemSize(void); ! extern BlockNumber GetPageWithFreeSpace(RelFileNode *rel, ! Size spaceNeeded, ! bool forInsert); extern BlockNumber RecordAndGetPageWithFreeSpace(RelFileNode *rel, BlockNumber oldPage, Size oldSpaceAvail, ! Size spaceNeeded, ! bool forInsert); extern Size GetAvgFSMRequestSize(RelFileNode *rel); extern void RecordRelationFreeSpace(RelFileNode *rel, int nPages,