*** a/src/backend/access/common/reloptions.c
--- b/src/backend/access/common/reloptions.c
***************
*** 85,90 **** static relopt_bool boolRelOpts[] =
--- 85,98 ----
  		},
  		false
  	},
+ 	{
+ 		{
+ 			"buffer_cache",
+ 			"Enables buffer_cache option Table/Index.",
+ 			RELOPT_KIND_HEAP | RELOPT_KIND_BTREE
+ 		},
+ 		false
+ 	},
  	/* list terminator */
  	{{NULL}}
  };
***************
*** 1230,1236 **** default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
  		{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
  		offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, analyze_scale_factor)},
  		{"user_catalog_table", RELOPT_TYPE_BOOL,
! 		offsetof(StdRdOptions, user_catalog_table)}
  	};
  
  	options = parseRelOptions(reloptions, validate, kind, &numoptions);
--- 1238,1246 ----
  		{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
  		offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, analyze_scale_factor)},
  		{"user_catalog_table", RELOPT_TYPE_BOOL,
! 		offsetof(StdRdOptions, user_catalog_table)},
! 		{"buffer_cache", RELOPT_TYPE_BOOL,
! 		offsetof(StdRdOptions, buffer_cache) }
  	};
  
  	options = parseRelOptions(reloptions, validate, kind, &numoptions);
*** a/src/backend/storage/buffer/buf_init.c
--- b/src/backend/storage/buffer/buf_init.c
***************
*** 18,23 ****
--- 18,24 ----
  #include "storage/buf_internals.h"
  
  
+ BufferPoolHeader *BufferPool;
  BufferDescPadded *BufferDescriptors;
  char	   *BufferBlocks;
  
***************
*** 65,71 **** void
  InitBufferPool(void)
  {
  	bool		foundBufs,
! 				foundDescs;
  
  	/* Align descriptors to a cacheline boundary. */
  	BufferDescriptors = (BufferDescPadded *) CACHELINEALIGN(
--- 66,78 ----
  InitBufferPool(void)
  {
  	bool		foundBufs,
! 				foundDescs,
! 				foundPoolHeader;
! 
! 	/* Initialize the Buffer Pool Header data */
! 	BufferPool = (BufferPoolHeader *)
! 						ShmemInitStruct("Buffer pool",
! 						sizeof(BufferPoolHeader), &foundPoolHeader);
  
  	/* Align descriptors to a cacheline boundary. */
  	BufferDescriptors = (BufferDescPadded *) CACHELINEALIGN(
***************
*** 116,121 **** InitBufferPool(void)
--- 123,131 ----
  
  		/* Correct last entry of linked list */
  		GetBufferDescriptor(NBuffers - 1)->freeNext = FREENEXT_END_OF_LIST;
+ 
+ 		pg_atomic_init_u32(&BufferPool->current_buffer_cache_pages, 0);
+ 		pg_atomic_init_u32(&BufferPool->max_buffer_cache_pages,((NBuffers * buffer_cache_ratio) / 100));
  	}
  
  	/* Init other shared buffer-management stuff */
***************
*** 133,138 **** BufferShmemSize(void)
--- 143,151 ----
  {
  	Size		size = 0;
  
+ 	/* size of buffer Pool Header */
+ 	size = add_size(size, sizeof(BufferPoolHeader));
+ 
  	/* size of buffer descriptors */
  	size = add_size(size, mul_size(NBuffers, sizeof(BufferDescPadded)));
  	/* to allow aligning buffer descriptors */
*** a/src/backend/storage/buffer/bufmgr.c
--- b/src/backend/storage/buffer/bufmgr.c
***************
*** 1171,1182 **** BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
  	 * 1 so that the buffer can survive one clock-sweep pass.)
  	 */
  	buf->tag = newTag;
! 	buf->flags &= ~(BM_VALID | BM_DIRTY | BM_JUST_DIRTIED | BM_CHECKPOINT_NEEDED | BM_IO_ERROR | BM_PERMANENT);
  	if (relpersistence == RELPERSISTENCE_PERMANENT)
  		buf->flags |= BM_TAG_VALID | BM_PERMANENT;
  	else
  		buf->flags |= BM_TAG_VALID;
  	buf->usage_count = 1;
  
  	UnlockBufHdr(buf);
  
--- 1171,1196 ----
  	 * 1 so that the buffer can survive one clock-sweep pass.)
  	 */
  	buf->tag = newTag;
! 	buf->flags &= ~(BM_VALID | BM_DIRTY | BM_JUST_DIRTIED | BM_CHECKPOINT_NEEDED | BM_IO_ERROR | BM_PERMANENT | BM_BUFFER_CACHE_PAGE);
  	if (relpersistence == RELPERSISTENCE_PERMANENT)
  		buf->flags |= BM_TAG_VALID | BM_PERMANENT;
  	else
  		buf->flags |= BM_TAG_VALID;
  	buf->usage_count = 1;
+ 	
+ 	if ((oldFlags & BM_BUFFER_CACHE_PAGE) && (smgr->is_a_buffer_cache_rel))
+ 	{
+ 		buf->flags |= BM_BUFFER_CACHE_PAGE;
+ 	}
+ 	else if (smgr->is_a_buffer_cache_rel)
+ 	{
+ 		buf->flags |= BM_BUFFER_CACHE_PAGE;
+ 		increment_buffer_cache_pages_counter();
+ 	}
+ 	else if (oldFlags & BM_BUFFER_CACHE_PAGE)
+ 	{
+ 		decrement_buffer_cache_pages_counter();
+ 	}
  
  	UnlockBufHdr(buf);
  
***************
*** 1288,1293 **** retry:
--- 1302,1310 ----
  	buf->flags = 0;
  	buf->usage_count = 0;
  
+ 	if (oldFlags & BM_BUFFER_CACHE_PAGE)
+ 		decrement_buffer_cache_pages_counter();
+ 
  	UnlockBufHdr(buf);
  
  	/*
*** a/src/backend/storage/buffer/freelist.c
--- b/src/backend/storage/buffer/freelist.c
***************
*** 101,106 **** typedef struct BufferAccessStrategyData
--- 101,129 ----
  static volatile BufferDesc *GetBufferFromRing(BufferAccessStrategy strategy);
  static void AddBufferToRing(BufferAccessStrategy strategy,
  				volatile BufferDesc *buf);
+ static bool is_buffer_cache_ratio_reached(void);
+ 
+ void
+ decrement_buffer_cache_pages_counter()
+ {
+ 	pg_atomic_fetch_sub_u32(&BufferPool->current_buffer_cache_pages, 1);
+ }
+ 
+ void
+ increment_buffer_cache_pages_counter()
+ {
+ 	pg_atomic_fetch_add_u32(&BufferPool->current_buffer_cache_pages, 1);
+ }
+ 
+ static bool
+ is_buffer_cache_ratio_reached()
+ {
+ 	uint32 current_pages = pg_atomic_read_u32(&BufferPool->current_buffer_cache_pages);
+ 	uint32 max_pages = pg_atomic_read_u32(&BufferPool->max_buffer_cache_pages);
+ 
+ 	return (current_pages < max_pages) ? false : true;
+ }
+ 
  
  /*
   * ClockSweepTick - Helper routine for StrategyGetBuffer()
***************
*** 305,313 **** StrategyGetBuffer(BufferAccessStrategy strategy)
  		LockBufHdr(buf);
  		if (buf->refcount == 0)
  		{
! 			if (buf->usage_count > 0)
  			{
  				buf->usage_count--;
  				trycounter = NBuffers;
  			}
  			else
--- 328,341 ----
  		LockBufHdr(buf);
  		if (buf->refcount == 0)
  		{
! 			if ((buf->flags & BM_BUFFER_CACHE_PAGE) && !is_buffer_cache_ratio_reached())
! 			{
! 				trycounter = NBuffers;
! 			}
! 			else if (buf->usage_count > 0)
  			{
  				buf->usage_count--;
+ 
  				trycounter = NBuffers;
  			}
  			else
*** a/src/backend/utils/init/globals.c
--- b/src/backend/utils/init/globals.c
***************
*** 116,121 **** int			maintenance_work_mem = 16384;
--- 116,122 ----
   * register background workers.
   */
  int			NBuffers = 1000;
+ int			buffer_cache_ratio = 0;
  int			MaxConnections = 90;
  int			max_worker_processes = 8;
  int			MaxBackends = 0;
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
***************
*** 1811,1816 **** static struct config_int ConfigureNamesInt[] =
--- 1811,1826 ----
  	},
  
  	{
+ 		{ "buffer_cache_ratio", PGC_POSTMASTER, RESOURCES_MEM,
+ 			gettext_noop("Sets the number of buffer cache ratio can be used for buffer cache relations from shared memory."),
+ 			NULL
+ 		},
+ 		&buffer_cache_ratio,
+ 		0, 0, 75,
+ 		NULL, NULL, NULL
+ 	},
+ 
+ 	{
  		{"temp_buffers", PGC_USERSET, RESOURCES_MEM,
  			gettext_noop("Sets the maximum number of temporary buffers used by each session."),
  			NULL,
*** a/src/backend/utils/misc/postgresql.conf.sample
--- b/src/backend/utils/misc/postgresql.conf.sample
***************
*** 114,119 ****
--- 114,122 ----
  
  #shared_buffers = 32MB			# min 128kB
  					# (change requires restart)
+ #buffer_cache_ratio = 0;	#specifies the ratio of shared buffers
+ 							#used for buffer cache relations
+ 							#(change requires restart)
  #huge_pages = try			# on, off, or try
  					# (change requires restart)
  #temp_buffers = 8MB			# min 800kB
*** a/src/bin/pgbench/pgbench.c
--- b/src/bin/pgbench/pgbench.c
***************
*** 1930,1938 **** init(bool is_no_vacuum)
  		}
  	};
  	static const char *const DDLINDEXes[] = {
! 		"alter table pgbench_branches add primary key (bid)",
! 		"alter table pgbench_tellers add primary key (tid)",
! 		"alter table pgbench_accounts add primary key (aid)"
  	};
  	static const char *const DDLKEYs[] = {
  		"alter table pgbench_tellers add foreign key (bid) references pgbench_branches",
--- 1930,1938 ----
  		}
  	};
  	static const char *const DDLINDEXes[] = {
! 		"alter table pgbench_branches add primary key (bid) with (buffer_cache=true)",
! 		"alter table pgbench_tellers add primary key (tid) with (buffer_cache=true)",
! 		"alter table pgbench_accounts add primary key (aid) with (buffer_cache=true)"
  	};
  	static const char *const DDLKEYs[] = {
  		"alter table pgbench_tellers add foreign key (bid) references pgbench_branches",
***************
*** 1973,1979 **** init(bool is_no_vacuum)
  		opts[0] = '\0';
  		if (ddl->declare_fillfactor)
  			snprintf(opts + strlen(opts), sizeof(opts) - strlen(opts),
! 					 " with (fillfactor=%d)", fillfactor);
  		if (tablespace != NULL)
  		{
  			char	   *escape_tablespace;
--- 1973,1983 ----
  		opts[0] = '\0';
  		if (ddl->declare_fillfactor)
  			snprintf(opts + strlen(opts), sizeof(opts) - strlen(opts),
! 					 " with (fillfactor=%d", fillfactor);
! 		
! 		snprintf(opts + strlen(opts), sizeof(opts) - strlen(opts),
! 			"%s buffer_cache=true)", ddl->declare_fillfactor ? ",":" with (");
! 		
  		if (tablespace != NULL)
  		{
  			char	   *escape_tablespace;
*** a/src/include/storage/buf_internals.h
--- b/src/include/storage/buf_internals.h
***************
*** 40,45 ****
--- 40,46 ----
  #define BM_CHECKPOINT_NEEDED	(1 << 7)		/* must write for checkpoint */
  #define BM_PERMANENT			(1 << 8)		/* permanent relation (not
  												 * unlogged) */
+ #define BM_BUFFER_CACHE_PAGE	(1 << 9)		/* Buffer used by a buffer cache rel */
  
  typedef bits16 BufFlags;
  
***************
*** 227,232 **** extern void StrategyNotifyBgWriter(int bgwprocno);
--- 228,236 ----
  extern Size StrategyShmemSize(void);
  extern void StrategyInitialize(bool init);
  
+ extern void decrement_buffer_cache_pages_counter(void);
+ extern void increment_buffer_cache_pages_counter(void);
+ 
  /* buf_table.c */
  extern Size BufTableShmemSize(int size);
  extern void InitBufTable(int size);
*** a/src/include/storage/bufmgr.h
--- b/src/include/storage/bufmgr.h
***************
*** 14,19 ****
--- 14,20 ----
  #ifndef BUFMGR_H
  #define BUFMGR_H
  
+ #include "port/atomics.h"
  #include "storage/block.h"
  #include "storage/buf.h"
  #include "storage/bufpage.h"
***************
*** 45,52 **** typedef enum
--- 46,61 ----
  								 * replay; otherwise same as RBM_NORMAL */
  } ReadBufferMode;
  
+ typedef struct BufferPoolHeader
+ {
+ 	pg_atomic_uint32	max_buffer_cache_pages;
+ 	pg_atomic_uint32	current_buffer_cache_pages;
+ } BufferPoolHeader;
+ 
  /* in globals.c ... this duplicates miscadmin.h */
  extern PGDLLIMPORT int NBuffers;
+ extern int buffer_cache_ratio;
+ extern BufferPoolHeader *BufferPool;
  
  /* in bufmgr.c */
  extern bool zero_damaged_pages;
*** a/src/include/storage/smgr.h
--- b/src/include/storage/smgr.h
***************
*** 56,61 **** typedef struct SMgrRelationData
--- 56,63 ----
  	BlockNumber smgr_fsm_nblocks;		/* last known size of fsm fork */
  	BlockNumber smgr_vm_nblocks;	/* last known size of vm fork */
  
+ 	bool		is_a_buffer_cache_rel;	/* Flag to indicate the relation buffer_cache */
+ 
  	/* additional public fields may someday exist here */
  
  	/*
*** a/src/include/utils/rel.h
--- b/src/include/utils/rel.h
***************
*** 220,225 **** typedef struct StdRdOptions
--- 220,227 ----
  	AutoVacOpts autovacuum;		/* autovacuum-related options */
  	bool		user_catalog_table;		/* use as an additional catalog
  										 * relation */
+ 	bool		buffer_cache;	/* Use buffer cache for relation 
+ 								 * if available */
  } StdRdOptions;
  
  #define HEAP_MIN_FILLFACTOR			10
***************
*** 256,261 **** typedef struct StdRdOptions
--- 258,270 ----
  	((relation)->rd_options ?				\
  	 ((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false)
  
+ /*
+  * RelationUsesBufferCache
+  *		Returns the relation's buffer_cache option.
+  */
+ #define RelationUsesBufferCache(relation) \
+ 	((relation)->rd_options ?				\
+ 	 ((StdRdOptions *) (relation)->rd_options)->buffer_cache : false)
  
  /*
   * ViewOptions
***************
*** 390,395 **** typedef struct ViewOptions
--- 399,405 ----
  	do { \
  		if ((relation)->rd_smgr == NULL) \
  			smgrsetowner(&((relation)->rd_smgr), smgropen((relation)->rd_node, (relation)->rd_backend)); \
+ 		(relation)->rd_smgr->is_a_buffer_cache_rel = RelationUsesBufferCache(relation); \
  	} while (0)
  
  /*
