aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/heap/hio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/heap/hio.c')
-rw-r--r--src/backend/access/heap/hio.c71
1 files changed, 37 insertions, 34 deletions
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index 5c727145f6f..462de54ccfd 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Id: hio.c,v 1.14 1998/11/27 19:51:36 vadim Exp $
+ * $Id: hio.c,v 1.15 1998/12/15 12:45:14 vadim Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,6 +15,7 @@
#include <postgres.h>
#include <storage/bufpage.h>
+#include <access/hio.h>
#include <access/heapam.h>
#include <storage/bufmgr.h>
#include <utils/memutils.h>
@@ -29,19 +30,20 @@
* Probably needs to have an amdelunique to allow for
* internal index records to be deleted and reordered as needed.
* For the heap AM, this should never be needed.
+ *
+ * Note - we assume that caller hold BUFFER_LOCK_EXCLUSIVE on the buffer.
+ *
*/
void
RelationPutHeapTuple(Relation relation,
- BlockNumber blockIndex,
+ Buffer buffer,
HeapTuple tuple)
{
- Buffer buffer;
- Page pageHeader;
- BlockNumber numberOfBlocks;
- OffsetNumber offnum;
- unsigned int len;
- ItemId itemId;
- Item item;
+ Page pageHeader;
+ OffsetNumber offnum;
+ unsigned int len;
+ ItemId itemId;
+ Item item;
/* ----------------
* increment access statistics
@@ -50,21 +52,6 @@ RelationPutHeapTuple(Relation relation,
IncrHeapAccessStat(local_RelationPutHeapTuple);
IncrHeapAccessStat(global_RelationPutHeapTuple);
- Assert(RelationIsValid(relation));
- Assert(HeapTupleIsValid(tuple));
-
- numberOfBlocks = RelationGetNumberOfBlocks(relation);
- Assert(blockIndex < numberOfBlocks);
-
- buffer = ReadBuffer(relation, blockIndex);
-#ifndef NO_BUFFERISVALID
- if (!BufferIsValid(buffer))
- {
- elog(ERROR, "RelationPutHeapTuple: no buffer for %ld in %s",
- blockIndex, &relation->rd_rel->relname);
- }
-#endif
-
pageHeader = (Page) BufferGetPage(buffer);
len = (unsigned) DOUBLEALIGN(tuple->t_len); /* be conservative */
Assert((int) len <= PageGetFreeSpace(pageHeader));
@@ -75,11 +62,17 @@ RelationPutHeapTuple(Relation relation,
itemId = PageGetItemId((Page) pageHeader, offnum);
item = PageGetItem((Page) pageHeader, itemId);
- ItemPointerSet(&((HeapTupleHeader) item)->t_ctid, blockIndex, offnum);
+ ItemPointerSet(&((HeapTupleHeader) item)->t_ctid,
+ BufferGetBlockNumber(buffer), offnum);
+ /*
+ * Let the caller do this!
+ *
WriteBuffer(buffer);
+ */
+
/* return an accurate tuple */
- ItemPointerSet(&tuple->t_self, blockIndex, offnum);
+ ItemPointerSet(&tuple->t_self, BufferGetBlockNumber(buffer), offnum);
}
/*
@@ -99,6 +92,7 @@ RelationPutHeapTuple(Relation relation,
* RelationGetNumberOfBlocks to be useful.
*
* NOTE: This code presumes that we have a write lock on the relation.
+ * Not now - we use extend locking...
*
* Also note that this routine probably shouldn't have to exist, and does
* screw up the call graph rather badly, but we are wasting so much time and
@@ -116,8 +110,8 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
ItemId itemId;
Item item;
- Assert(RelationIsValid(relation));
- Assert(HeapTupleIsValid(tuple));
+ if (!relation->rd_islocal)
+ LockRelation(relation, ExtendLock);
/*
* XXX This does an lseek - VERY expensive - but at the moment it is
@@ -132,16 +126,18 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
{
buffer = ReadBuffer(relation, lastblock);
pageHeader = (Page) BufferGetPage(buffer);
- if (PageIsNew((PageHeader) pageHeader))
- {
- buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
- pageHeader = (Page) BufferGetPage(buffer);
- PageInit(pageHeader, BufferGetPageSize(buffer), 0);
- }
+ /*
+ * There was IF instead of ASSERT here ?!
+ */
+ Assert(PageIsNew((PageHeader) pageHeader));
+ buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
+ pageHeader = (Page) BufferGetPage(buffer);
+ PageInit(pageHeader, BufferGetPageSize(buffer), 0);
}
else
buffer = ReadBuffer(relation, lastblock - 1);
+ LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
pageHeader = (Page) BufferGetPage(buffer);
len = (unsigned) DOUBLEALIGN(tuple->t_len); /* be conservative */
@@ -152,7 +148,9 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
if (len > PageGetFreeSpace(pageHeader))
{
+ LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
+ LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
pageHeader = (Page) BufferGetPage(buffer);
PageInit(pageHeader, BufferGetPageSize(buffer), 0);
@@ -160,6 +158,9 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
elog(ERROR, "Tuple is too big: size %d", len);
}
+ if (!relation->rd_islocal)
+ UnlockRelation(relation, ExtendLock);
+
offnum = PageAddItem((Page) pageHeader, (Item) tuple->t_data,
tuple->t_len, InvalidOffsetNumber, LP_USED);
@@ -173,5 +174,7 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
/* return an accurate tuple */
ItemPointerSet(&tuple->t_self, lastblock, offnum);
+ LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
WriteBuffer(buffer);
+
}