Blowaway relation buffers from buffer pool before truncation:
authorVadim B. Mikheev
Mon, 22 Sep 1997 07:13:56 +0000 (07:13 +0000)
committerVadim B. Mikheev
Mon, 22 Sep 1997 07:13:56 +0000 (07:13 +0000)
+ BlowawayRelationBuffers(relation, blocknumber)

src/backend/storage/buffer/bufmgr.c

index b29a5e76cac08c02a7849ba2231a60c03718d296..ae249eed2aa76e7dd7a1d743ac2743042055be41 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.25 1997/09/18 20:21:21 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.26 1997/09/22 07:13:56 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -99,6 +99,9 @@ static int    FlushBuffer(Buffer buffer, bool release);
 static void BufferSync(void);
 static int BufferReplace(BufferDesc *bufHdr, bool bufferLockHeld);
 
+/* not static but used by vacuum only ... */
+int BlowawayRelationBuffers(Relation rdesc, BlockNumber block);
+
 /* ---------------------------------------------------
  * RelationGetBufferWithBuffer
  *     see if the given buffer is what we want
@@ -1603,6 +1606,67 @@ BufferPoolBlowaway()
 
 #endif
 
+/* ---------------------------------------------------------------------
+ *     BlowawayRelationBuffers
+ *
+ *     This function blowaway all the pages with blocknumber >= passed
+ *     of a relation in the buffer pool. Used by vacuum before truncation...
+ *     
+ *     Returns: 0 - Ok, -1 - DIRTY, -2 - PINNED
+ *     
+ *     XXX currently it sequentially searches the buffer pool, should be
+ *     changed to more clever ways of searching.
+ * --------------------------------------------------------------------
+ */
+int
+BlowawayRelationBuffers(Relation rdesc, BlockNumber block)
+{
+   register int    i;
+   BufferDesc     *buf;
+
+   if (rdesc->rd_islocal)
+   {
+       for (i = 0; i < NLocBuffer; i++)
+       {
+           buf = &LocalBufferDescriptors[i];
+           if (buf->tag.relId.relId == rdesc->rd_id && 
+               buf->tag.blockNum >= block)
+           {
+               if (buf->flags & BM_DIRTY)
+                   return (-1);
+               if (LocalRefCount[i] > 0)
+                   return (-2);
+               buf->tag.relId.relId = InvalidOid;
+           }
+       }
+       return (0);
+   }
+
+   SpinAcquire(BufMgrLock);
+   for (i = 0; i < NBuffers; i++)
+   {
+       buf = &BufferDescriptors[i];
+       if (buf->tag.relId.dbId == MyDatabaseId &&
+           buf->tag.relId.relId == rdesc->rd_id && 
+           buf->tag.blockNum >= block)
+       {
+           if (buf->flags & BM_DIRTY)
+           {
+               SpinRelease(BufMgrLock);
+               return (-1);
+           }
+           if (!(buf->flags & BM_FREE))
+           {
+               SpinRelease(BufMgrLock);
+               return (-2);
+           }
+           BufTableDelete(buf);
+       }
+   }
+   SpinRelease(BufMgrLock);
+   return (0);
+}
+
 #undef IncrBufferRefCount
 #undef ReleaseBuffer