mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	Add cache invalidation callback hooks.
This commit is contained in:
		
							parent
							
								
									8d615763da
								
							
						
					
					
						commit
						88ef7067f7
					
				
							
								
								
									
										100
									
								
								src/backend/utils/cache/inval.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										100
									
								
								src/backend/utils/cache/inval.c
									
									
									
									
										vendored
									
									
								
							| @ -74,7 +74,7 @@ | ||||
|  * Portions Copyright (c) 1994, Regents of the University of California | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.50 2002/04/12 20:38:28 tgl Exp $ | ||||
|  *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.51 2002/04/29 22:14:34 tgl Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @ -109,8 +109,7 @@ typedef struct InvalidationListHeader | ||||
| 	InvalidationChunk *rclist;	/* list of chunks holding relcache msgs */ | ||||
| } InvalidationListHeader; | ||||
| 
 | ||||
| /*
 | ||||
|  * ---------------- | ||||
| /*----------------
 | ||||
|  *	Invalidation info is divided into two lists: | ||||
|  *	1) events so far in current command, not yet reflected to caches. | ||||
|  *	2) events in previous commands of current transaction; these have | ||||
| @ -132,6 +131,22 @@ static InvalidationListHeader PriorCmdInvalidMsgs; | ||||
| 
 | ||||
| static bool RelcacheInitFileInval; /* init file must be invalidated? */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Dynamically-registered callback functions.  Current implementation | ||||
|  * assumes there won't be very many of these at once; could improve if needed. | ||||
|  */ | ||||
| 
 | ||||
| #define MAX_CACHE_CALLBACKS 20 | ||||
| 
 | ||||
| static struct CACHECALLBACK | ||||
| { | ||||
| 	int16		id;				/* cache number or SHAREDINVALRELCACHE_ID */ | ||||
| 	CacheCallbackFunction function; | ||||
| 	Datum		arg; | ||||
| }	cache_callback_list[MAX_CACHE_CALLBACKS]; | ||||
| 
 | ||||
| static int	cache_callback_count = 0; | ||||
| 
 | ||||
| 
 | ||||
| /* ----------------------------------------------------------------
 | ||||
|  *				Invalidation list support functions | ||||
| @ -398,17 +413,39 @@ RegisterRelcacheInvalidation(Oid dbId, Oid relId) | ||||
| static void | ||||
| LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg) | ||||
| { | ||||
| 	int			i; | ||||
| 
 | ||||
| 	if (msg->id >= 0) | ||||
| 	{ | ||||
| 		if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == 0) | ||||
| 		{ | ||||
| 			CatalogCacheIdInvalidate(msg->cc.id, | ||||
| 									 msg->cc.hashValue, | ||||
| 									 &msg->cc.tuplePtr); | ||||
| 
 | ||||
| 			for (i = 0; i < cache_callback_count; i++) | ||||
| 			{ | ||||
| 				struct CACHECALLBACK *ccitem = cache_callback_list + i; | ||||
| 
 | ||||
| 				if (ccitem->id == msg->cc.id) | ||||
| 					(*ccitem->function) (ccitem->arg, InvalidOid); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	else if (msg->id == SHAREDINVALRELCACHE_ID) | ||||
| 	{ | ||||
| 		if (msg->rc.dbId == MyDatabaseId || msg->rc.dbId == 0) | ||||
| 		{ | ||||
| 			RelationIdInvalidateRelationCacheByRelationId(msg->rc.relId); | ||||
| 
 | ||||
| 			for (i = 0; i < cache_callback_count; i++) | ||||
| 			{ | ||||
| 				struct CACHECALLBACK *ccitem = cache_callback_list + i; | ||||
| 
 | ||||
| 				if (ccitem->id == SHAREDINVALRELCACHE_ID) | ||||
| 					(*ccitem->function) (ccitem->arg, msg->rc.relId); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| @ -431,8 +468,17 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg) | ||||
| static void | ||||
| InvalidateSystemCaches(void) | ||||
| { | ||||
| 	int			i; | ||||
| 
 | ||||
| 	ResetCatalogCaches(); | ||||
| 	RelationCacheInvalidate(); | ||||
| 
 | ||||
| 	for (i = 0; i < cache_callback_count; i++) | ||||
| 	{ | ||||
| 		struct CACHECALLBACK *ccitem = cache_callback_list + i; | ||||
| 
 | ||||
| 		(*ccitem->function) (ccitem->arg, InvalidOid); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
| @ -640,3 +686,51 @@ CacheInvalidateRelcache(Oid relationId) | ||||
| 	/* See KLUGE ALERT in PrepareForTupleInvalidation */ | ||||
| 	RegisterRelcacheInvalidation(MyDatabaseId, relationId); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * CacheRegisterSyscacheCallback | ||||
|  *		Register the specified function to be called for all future | ||||
|  *		invalidation events in the specified cache. | ||||
|  * | ||||
|  * NOTE: currently, the OID argument to the callback routine is not | ||||
|  * provided for syscache callbacks; the routine doesn't really get any | ||||
|  * useful info as to exactly what changed.  It should treat every call | ||||
|  * as a "cache flush" request. | ||||
|  */ | ||||
| void | ||||
| CacheRegisterSyscacheCallback(int cacheid, | ||||
| 							  CacheCallbackFunction func, | ||||
| 							  Datum arg) | ||||
| { | ||||
| 	if (cache_callback_count >= MAX_CACHE_CALLBACKS) | ||||
| 		elog(FATAL, "Out of cache_callback_list slots"); | ||||
| 
 | ||||
| 	cache_callback_list[cache_callback_count].id = cacheid; | ||||
| 	cache_callback_list[cache_callback_count].function = func; | ||||
| 	cache_callback_list[cache_callback_count].arg = arg; | ||||
| 
 | ||||
| 	++cache_callback_count; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * CacheRegisterRelcacheCallback | ||||
|  *		Register the specified function to be called for all future | ||||
|  *		relcache invalidation events.  The OID of the relation being | ||||
|  *		invalidated will be passed to the function. | ||||
|  * | ||||
|  * NOTE: InvalidOid will be passed if a cache reset request is received. | ||||
|  * In this case the called routines should flush all cached state. | ||||
|  */ | ||||
| void | ||||
| CacheRegisterRelcacheCallback(CacheCallbackFunction func, | ||||
| 							  Datum arg) | ||||
| { | ||||
| 	if (cache_callback_count >= MAX_CACHE_CALLBACKS) | ||||
| 		elog(FATAL, "Out of cache_callback_list slots"); | ||||
| 
 | ||||
| 	cache_callback_list[cache_callback_count].id = SHAREDINVALRELCACHE_ID; | ||||
| 	cache_callback_list[cache_callback_count].function = func; | ||||
| 	cache_callback_list[cache_callback_count].arg = arg; | ||||
| 
 | ||||
| 	++cache_callback_count; | ||||
| } | ||||
|  | ||||
| @ -7,7 +7,7 @@ | ||||
|  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group | ||||
|  * Portions Copyright (c) 1994, Regents of the University of California | ||||
|  * | ||||
|  * $Id: inval.h,v 1.24 2002/03/03 17:47:56 tgl Exp $ | ||||
|  * $Id: inval.h,v 1.25 2002/04/29 22:14:34 tgl Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @ -17,6 +17,9 @@ | ||||
| #include "access/htup.h" | ||||
| 
 | ||||
| 
 | ||||
| typedef void (*CacheCallbackFunction) (Datum arg, Oid relid); | ||||
| 
 | ||||
| 
 | ||||
| extern void AcceptInvalidationMessages(void); | ||||
| 
 | ||||
| extern void AtEOXactInvalidationMessages(bool isCommit); | ||||
| @ -27,4 +30,11 @@ extern void CacheInvalidateHeapTuple(Relation relation, HeapTuple tuple); | ||||
| 
 | ||||
| extern void CacheInvalidateRelcache(Oid relationId); | ||||
| 
 | ||||
| extern void CacheRegisterSyscacheCallback(int cacheid, | ||||
| 										  CacheCallbackFunction func, | ||||
| 										  Datum arg); | ||||
| 
 | ||||
| extern void CacheRegisterRelcacheCallback(CacheCallbackFunction func, | ||||
| 										  Datum arg); | ||||
| 
 | ||||
| #endif   /* INVAL_H */ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user