MCPcopy Create free account
hub / github.com/apache/cloudberry / ReadRecentBuffer

Function ReadRecentBuffer

src/backend/storage/buffer/bufmgr.c:704–774  ·  view source on GitHub ↗

* ReadRecentBuffer -- try to pin a block in a recently observed buffer * * Compared to ReadBuffer(), this avoids a buffer mapping lookup when it's * successful. Return true if the buffer is valid and still has the expected * tag. In that case, the buffer is pinned and the usage count is bumped. */

Source from the content-addressed store, hash-verified

702 * tag. In that case, the buffer is pinned and the usage count is bumped.
703 */
704bool
705ReadRecentBuffer(RelFileNode rnode, ForkNumber forkNum, BlockNumber blockNum,
706 Buffer recent_buffer)
707{
708 BufferDesc *bufHdr;
709 BufferTag tag;
710 uint32 buf_state;
711 bool have_private_ref;
712
713 Assert(BufferIsValid(recent_buffer));
714
715 ResourceOwnerEnlargeBuffers(CurrentResourceOwner);
716 ReservePrivateRefCountEntry();
717 INIT_BUFFERTAG(tag, rnode, forkNum, blockNum);
718
719 if (BufferIsLocal(recent_buffer))
720 {
721 bufHdr = GetBufferDescriptor(-recent_buffer - 1);
722 buf_state = pg_atomic_read_u32(&bufHdr->state);
723
724 /* Is it still valid and holding the right tag? */
725 if ((buf_state & BM_VALID) && BUFFERTAGS_EQUAL(tag, bufHdr->tag))
726 {
727 /* Bump local buffer's ref and usage counts. */
728 ResourceOwnerRememberBuffer(CurrentResourceOwner, recent_buffer);
729 LocalRefCount[-recent_buffer - 1]++;
730 if (BUF_STATE_GET_USAGECOUNT(buf_state) < BM_MAX_USAGE_COUNT)
731 pg_atomic_write_u32(&bufHdr->state,
732 buf_state + BUF_USAGECOUNT_ONE);
733
734 return true;
735 }
736 }
737 else
738 {
739 bufHdr = GetBufferDescriptor(recent_buffer - 1);
740 have_private_ref = GetPrivateRefCount(recent_buffer) > 0;
741
742 /*
743 * Do we already have this buffer pinned with a private reference? If
744 * so, it must be valid and it is safe to check the tag without
745 * locking. If not, we have to lock the header first and then check.
746 */
747 if (have_private_ref)
748 buf_state = pg_atomic_read_u32(&bufHdr->state);
749 else
750 buf_state = LockBufHdr(bufHdr);
751
752 if ((buf_state & BM_VALID) && BUFFERTAGS_EQUAL(tag, bufHdr->tag))
753 {
754 /*
755 * It's now safe to pin the buffer. We can't pin first and ask
756 * questions later, because because it might confuse code paths
757 * like InvalidateBuffer() if we pinned a random non-matching
758 * buffer.
759 */
760 if (have_private_ref)
761 PinBuffer(bufHdr, NULL); /* bump pin count */

Callers

nothing calls this directly

Calls 9

pg_atomic_read_u32Function · 0.85
pg_atomic_write_u32Function · 0.85
GetPrivateRefCountFunction · 0.85
LockBufHdrFunction · 0.85
PinBufferFunction · 0.85
PinBuffer_LockedFunction · 0.85

Tested by

no test coverage detected