88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/access/hash/hashovfl.c,v 1.56 2007/04/19 20:24:04 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/access/hash/hashovfl.c,v 1.57 2007/05/03 16:45:58 tgl Exp $
1212 *
1313 * NOTES
1414 * Overflow pages look like ordinary relation pages.
@@ -107,20 +107,21 @@ _hash_addovflpage(Relation rel, Buffer metabuf, Buffer buf)
107107
108108/* allocate and lock an empty overflow page */
109109ovflbuf = _hash_getovflpage (rel ,metabuf );
110- ovflpage = BufferGetPage (ovflbuf );
111110
112111/*
113112 * Write-lock the tail page. It is okay to hold two buffer locks here
114113 * since there cannot be anyone else contending for access to ovflbuf.
115114 */
116115_hash_chgbufaccess (rel ,buf ,HASH_NOLOCK ,HASH_WRITE );
117116
117+ /* probably redundant... */
118+ _hash_checkpage (rel ,buf ,LH_BUCKET_PAGE |LH_OVERFLOW_PAGE );
119+
118120/* loop to find current tail page, in case someone else inserted too */
119121for (;;)
120122{
121123BlockNumber nextblkno ;
122124
123- _hash_checkpage (rel ,buf ,LH_BUCKET_PAGE |LH_OVERFLOW_PAGE );
124125page = BufferGetPage (buf );
125126pageopaque = (HashPageOpaque )PageGetSpecialPointer (page );
126127nextblkno = pageopaque -> hasho_nextblkno ;
@@ -131,11 +132,11 @@ _hash_addovflpage(Relation rel, Buffer metabuf, Buffer buf)
131132/* we assume we do not need to write the unmodified page */
132133_hash_relbuf (rel ,buf );
133134
134- buf = _hash_getbuf (rel ,nextblkno ,HASH_WRITE );
135+ buf = _hash_getbuf (rel ,nextblkno ,HASH_WRITE , LH_OVERFLOW_PAGE );
135136}
136137
137138/* now that we have correct backlink, initialize new overflow page */
138- _hash_pageinit ( ovflpage , BufferGetPageSize (ovflbuf ) );
139+ ovflpage = BufferGetPage (ovflbuf );
139140ovflopaque = (HashPageOpaque )PageGetSpecialPointer (ovflpage );
140141ovflopaque -> hasho_prevblkno = BufferGetBlockNumber (buf );
141142ovflopaque -> hasho_nextblkno = InvalidBlockNumber ;
@@ -156,7 +157,8 @@ _hash_addovflpage(Relation rel, Buffer metabuf, Buffer buf)
156157 *_hash_getovflpage()
157158 *
158159 *Find an available overflow page and return it. The returned buffer
159- *is pinned and write-locked, but its contents are not initialized.
160+ *is pinned and write-locked, and has had _hash_pageinit() applied,
161+ *but it is caller's responsibility to fill the special space.
160162 *
161163 * The caller must hold a pin, but no lock, on the metapage buffer.
162164 * That buffer is left in the same state at exit.
@@ -220,8 +222,7 @@ _hash_getovflpage(Relation rel, Buffer metabuf)
220222/* Release exclusive lock on metapage while reading bitmap page */
221223_hash_chgbufaccess (rel ,metabuf ,HASH_READ ,HASH_NOLOCK );
222224
223- mapbuf = _hash_getbuf (rel ,mapblkno ,HASH_WRITE );
224- _hash_checkpage (rel ,mapbuf ,LH_BITMAP_PAGE );
225+ mapbuf = _hash_getbuf (rel ,mapblkno ,HASH_WRITE ,LH_BITMAP_PAGE );
225226mappage = BufferGetPage (mapbuf );
226227freep = HashPageGetBitmap (mappage );
227228
@@ -277,7 +278,7 @@ _hash_getovflpage(Relation rel, Buffer metabuf)
277278 * with metapage write lock held; would be better to use a lock that
278279 * doesn't block incoming searches.
279280 */
280- newbuf = _hash_getnewbuf (rel ,blkno , HASH_WRITE );
281+ newbuf = _hash_getnewbuf (rel ,blkno );
281282
282283metap -> hashm_spares [splitnum ]++ ;
283284
@@ -327,8 +328,8 @@ _hash_getovflpage(Relation rel, Buffer metabuf)
327328_hash_chgbufaccess (rel ,metabuf ,HASH_READ ,HASH_NOLOCK );
328329}
329330
330- /* Fetch and return the recycled page */
331- return _hash_getbuf (rel ,blkno , HASH_WRITE );
331+ /* Fetch, init, and return the recycled page */
332+ return _hash_getinitbuf (rel ,blkno );
332333}
333334
334335/*
@@ -412,30 +413,29 @@ _hash_freeovflpage(Relation rel, Buffer ovflbuf)
412413 */
413414if (BlockNumberIsValid (prevblkno ))
414415{
415- Buffer prevbuf = _hash_getbuf (rel ,prevblkno ,HASH_WRITE );
416+ Buffer prevbuf = _hash_getbuf (rel ,prevblkno ,HASH_WRITE ,
417+ LH_BUCKET_PAGE |LH_OVERFLOW_PAGE );
416418Page prevpage = BufferGetPage (prevbuf );
417419HashPageOpaque prevopaque = (HashPageOpaque )PageGetSpecialPointer (prevpage );
418420
419- _hash_checkpage (rel ,prevbuf ,LH_BUCKET_PAGE |LH_OVERFLOW_PAGE );
420421Assert (prevopaque -> hasho_bucket == bucket );
421422prevopaque -> hasho_nextblkno = nextblkno ;
422423_hash_wrtbuf (rel ,prevbuf );
423424}
424425if (BlockNumberIsValid (nextblkno ))
425426{
426- Buffer nextbuf = _hash_getbuf (rel ,nextblkno ,HASH_WRITE );
427+ Buffer nextbuf = _hash_getbuf (rel ,nextblkno ,HASH_WRITE ,
428+ LH_OVERFLOW_PAGE );
427429Page nextpage = BufferGetPage (nextbuf );
428430HashPageOpaque nextopaque = (HashPageOpaque )PageGetSpecialPointer (nextpage );
429431
430- _hash_checkpage (rel ,nextbuf ,LH_OVERFLOW_PAGE );
431432Assert (nextopaque -> hasho_bucket == bucket );
432433nextopaque -> hasho_prevblkno = prevblkno ;
433434_hash_wrtbuf (rel ,nextbuf );
434435}
435436
436437/* Read the metapage so we can determine which bitmap page to use */
437- metabuf = _hash_getbuf (rel ,HASH_METAPAGE ,HASH_READ );
438- _hash_checkpage (rel ,metabuf ,LH_META_PAGE );
438+ metabuf = _hash_getbuf (rel ,HASH_METAPAGE ,HASH_READ ,LH_META_PAGE );
439439metap = (HashMetaPage )BufferGetPage (metabuf );
440440
441441/* Identify which bit to set */
@@ -452,8 +452,7 @@ _hash_freeovflpage(Relation rel, Buffer ovflbuf)
452452_hash_chgbufaccess (rel ,metabuf ,HASH_READ ,HASH_NOLOCK );
453453
454454/* Clear the bitmap bit to indicate that this overflow page is free */
455- mapbuf = _hash_getbuf (rel ,blkno ,HASH_WRITE );
456- _hash_checkpage (rel ,mapbuf ,LH_BITMAP_PAGE );
455+ mapbuf = _hash_getbuf (rel ,blkno ,HASH_WRITE ,LH_BITMAP_PAGE );
457456mappage = BufferGetPage (mapbuf );
458457freep = HashPageGetBitmap (mappage );
459458Assert (ISSET (freep ,bitmapbit ));
@@ -507,11 +506,10 @@ _hash_initbitmap(Relation rel, HashMetaPage metap, BlockNumber blkno)
507506 * page while holding the metapage lock, but this path is taken so seldom
508507 * that it's not worth worrying about.
509508 */
510- buf = _hash_getnewbuf (rel ,blkno , HASH_WRITE );
509+ buf = _hash_getnewbuf (rel ,blkno );
511510pg = BufferGetPage (buf );
512511
513- /* initialize the page */
514- _hash_pageinit (pg ,BufferGetPageSize (buf ));
512+ /* initialize the page's special space */
515513op = (HashPageOpaque )PageGetSpecialPointer (pg );
516514op -> hasho_prevblkno = InvalidBlockNumber ;
517515op -> hasho_nextblkno = InvalidBlockNumber ;
@@ -583,8 +581,7 @@ _hash_squeezebucket(Relation rel,
583581 * start squeezing into the base bucket page.
584582 */
585583wblkno = bucket_blkno ;
586- wbuf = _hash_getbuf (rel ,wblkno ,HASH_WRITE );
587- _hash_checkpage (rel ,wbuf ,LH_BUCKET_PAGE );
584+ wbuf = _hash_getbuf (rel ,wblkno ,HASH_WRITE ,LH_BUCKET_PAGE );
588585wpage = BufferGetPage (wbuf );
589586wopaque = (HashPageOpaque )PageGetSpecialPointer (wpage );
590587
@@ -607,8 +604,7 @@ _hash_squeezebucket(Relation rel,
607604rblkno = ropaque -> hasho_nextblkno ;
608605if (ropaque != wopaque )
609606_hash_relbuf (rel ,rbuf );
610- rbuf = _hash_getbuf (rel ,rblkno ,HASH_WRITE );
611- _hash_checkpage (rel ,rbuf ,LH_OVERFLOW_PAGE );
607+ rbuf = _hash_getbuf (rel ,rblkno ,HASH_WRITE ,LH_OVERFLOW_PAGE );
612608rpage = BufferGetPage (rbuf );
613609ropaque = (HashPageOpaque )PageGetSpecialPointer (rpage );
614610Assert (ropaque -> hasho_bucket == bucket );
@@ -648,8 +644,7 @@ _hash_squeezebucket(Relation rel,
648644return ;
649645}
650646
651- wbuf = _hash_getbuf (rel ,wblkno ,HASH_WRITE );
652- _hash_checkpage (rel ,wbuf ,LH_OVERFLOW_PAGE );
647+ wbuf = _hash_getbuf (rel ,wblkno ,HASH_WRITE ,LH_OVERFLOW_PAGE );
653648wpage = BufferGetPage (wbuf );
654649wopaque = (HashPageOpaque )PageGetSpecialPointer (wpage );
655650Assert (wopaque -> hasho_bucket == bucket );
@@ -701,8 +696,7 @@ _hash_squeezebucket(Relation rel,
701696/* free this overflow page, then get the previous one */
702697_hash_freeovflpage (rel ,rbuf );
703698
704- rbuf = _hash_getbuf (rel ,rblkno ,HASH_WRITE );
705- _hash_checkpage (rel ,rbuf ,LH_OVERFLOW_PAGE );
699+ rbuf = _hash_getbuf (rel ,rblkno ,HASH_WRITE ,LH_OVERFLOW_PAGE );
706700rpage = BufferGetPage (rbuf );
707701ropaque = (HashPageOpaque )PageGetSpecialPointer (rpage );
708702Assert (ropaque -> hasho_bucket == bucket );