mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-04 00:02:52 -05:00 
			
		
		
		
	Use streaming I/O in pg_prewarm.
Instead of calling ReadBuffer() repeatedly, use the new streaming interface. This commit provides a very simple example of such a transformation. Discussion: https://postgr.es/m/CA+hUKGJkOiOCa+mag4BF+zHo7qo=o9CFheB8=g6uT5TUm2gkvA@mail.gmail.com
This commit is contained in:
		
							parent
							
								
									b5a9b18cd0
								
							
						
					
					
						commit
						3a352df05e
					
				@ -19,6 +19,7 @@
 | 
			
		||||
#include "fmgr.h"
 | 
			
		||||
#include "miscadmin.h"
 | 
			
		||||
#include "storage/bufmgr.h"
 | 
			
		||||
#include "storage/read_stream.h"
 | 
			
		||||
#include "storage/smgr.h"
 | 
			
		||||
#include "utils/acl.h"
 | 
			
		||||
#include "utils/builtins.h"
 | 
			
		||||
@ -38,6 +39,25 @@ typedef enum
 | 
			
		||||
 | 
			
		||||
static PGIOAlignedBlock blockbuffer;
 | 
			
		||||
 | 
			
		||||
struct pg_prewarm_read_stream_private
 | 
			
		||||
{
 | 
			
		||||
	BlockNumber blocknum;
 | 
			
		||||
	int64		last_block;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static BlockNumber
 | 
			
		||||
pg_prewarm_read_stream_next_block(ReadStream *stream,
 | 
			
		||||
								  void *callback_private_data,
 | 
			
		||||
								  void *per_buffer_data)
 | 
			
		||||
{
 | 
			
		||||
	struct pg_prewarm_read_stream_private *p = callback_private_data;
 | 
			
		||||
 | 
			
		||||
	if (p->blocknum <= p->last_block)
 | 
			
		||||
		return p->blocknum++;
 | 
			
		||||
 | 
			
		||||
	return InvalidBlockNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * pg_prewarm(regclass, mode text, fork text,
 | 
			
		||||
 *			  first_block int8, last_block int8)
 | 
			
		||||
@ -183,18 +203,36 @@ pg_prewarm(PG_FUNCTION_ARGS)
 | 
			
		||||
	}
 | 
			
		||||
	else if (ptype == PREWARM_BUFFER)
 | 
			
		||||
	{
 | 
			
		||||
		struct pg_prewarm_read_stream_private p;
 | 
			
		||||
		ReadStream *stream;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * In buffer mode, we actually pull the data into shared_buffers.
 | 
			
		||||
		 */
 | 
			
		||||
 | 
			
		||||
		/* Set up the private state for our streaming buffer read callback. */
 | 
			
		||||
		p.blocknum = first_block;
 | 
			
		||||
		p.last_block = last_block;
 | 
			
		||||
 | 
			
		||||
		stream = read_stream_begin_relation(READ_STREAM_FULL,
 | 
			
		||||
											NULL,
 | 
			
		||||
											rel,
 | 
			
		||||
											forkNumber,
 | 
			
		||||
											pg_prewarm_read_stream_next_block,
 | 
			
		||||
											&p,
 | 
			
		||||
											0);
 | 
			
		||||
 | 
			
		||||
		for (block = first_block; block <= last_block; ++block)
 | 
			
		||||
		{
 | 
			
		||||
			Buffer		buf;
 | 
			
		||||
 | 
			
		||||
			CHECK_FOR_INTERRUPTS();
 | 
			
		||||
			buf = ReadBufferExtended(rel, forkNumber, block, RBM_NORMAL, NULL);
 | 
			
		||||
			buf = read_stream_next_buffer(stream, NULL);
 | 
			
		||||
			ReleaseBuffer(buf);
 | 
			
		||||
			++blocks_done;
 | 
			
		||||
		}
 | 
			
		||||
		Assert(read_stream_next_buffer(stream, NULL) == InvalidBuffer);
 | 
			
		||||
		read_stream_end(stream);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Close relation, release lock. */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user