Skip to content

Commit 88ef706

Browse files
committed
Add cache invalidation callback hooks.
1 parent 8d61576 commit 88ef706

File tree

2 files changed

+109
-5
lines changed

2 files changed

+109
-5
lines changed

src/backend/utils/cache/inval.c

Lines changed: 98 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
* Portions Copyright (c) 1994, Regents of the University of California
7575
*
7676
* IDENTIFICATION
77-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.50 2002/04/12 20:38:28 tgl Exp $
77+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.51 2002/04/29 22:14:34 tgl Exp $
7878
*
7979
*-------------------------------------------------------------------------
8080
*/
@@ -109,8 +109,7 @@ typedef struct InvalidationListHeader
109109
InvalidationChunk *rclist; /* list of chunks holding relcache msgs */
110110
} InvalidationListHeader;
111111

112-
/*
113-
* ----------------
112+
/*----------------
114113
* Invalidation info is divided into two lists:
115114
* 1) events so far in current command, not yet reflected to caches.
116115
* 2) events in previous commands of current transaction; these have
@@ -121,7 +120,7 @@ typedef struct InvalidationListHeader
121120
* The relcache-file-invalidated flag can just be a simple boolean,
122121
* since we only act on it at transaction commit; we don't care which
123122
* command of the transaction set it.
124-
* ----------------
123+
*----------------
125124
*/
126125

127126
/* head of current-command event list */
@@ -132,6 +131,22 @@ static InvalidationListHeader PriorCmdInvalidMsgs;
132131

133132
static bool RelcacheInitFileInval; /* init file must be invalidated? */
134133

134+
/*
135+
* Dynamically-registered callback functions. Current implementation
136+
* assumes there won't be very many of these at once; could improve if needed.
137+
*/
138+
139+
#define MAX_CACHE_CALLBACKS 20
140+
141+
static struct CACHECALLBACK
142+
{
143+
int16 id; /* cache number or SHAREDINVALRELCACHE_ID */
144+
CacheCallbackFunction function;
145+
Datum arg;
146+
} cache_callback_list[MAX_CACHE_CALLBACKS];
147+
148+
static int cache_callback_count = 0;
149+
135150

136151
/* ----------------------------------------------------------------
137152
* Invalidation list support functions
@@ -398,17 +413,39 @@ RegisterRelcacheInvalidation(Oid dbId, Oid relId)
398413
static void
399414
LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
400415
{
416+
int i;
417+
401418
if (msg->id >= 0)
402419
{
403420
if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == 0)
421+
{
404422
CatalogCacheIdInvalidate(msg->cc.id,
405423
msg->cc.hashValue,
406424
&msg->cc.tuplePtr);
425+
426+
for (i = 0; i < cache_callback_count; i++)
427+
{
428+
struct CACHECALLBACK *ccitem = cache_callback_list + i;
429+
430+
if (ccitem->id == msg->cc.id)
431+
(*ccitem->function) (ccitem->arg, InvalidOid);
432+
}
433+
}
407434
}
408435
else if (msg->id == SHAREDINVALRELCACHE_ID)
409436
{
410437
if (msg->rc.dbId == MyDatabaseId || msg->rc.dbId == 0)
438+
{
411439
RelationIdInvalidateRelationCacheByRelationId(msg->rc.relId);
440+
441+
for (i = 0; i < cache_callback_count; i++)
442+
{
443+
struct CACHECALLBACK *ccitem = cache_callback_list + i;
444+
445+
if (ccitem->id == SHAREDINVALRELCACHE_ID)
446+
(*ccitem->function) (ccitem->arg, msg->rc.relId);
447+
}
448+
}
412449
}
413450
else
414451
{
@@ -431,8 +468,17 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
431468
static void
432469
InvalidateSystemCaches(void)
433470
{
471+
int i;
472+
434473
ResetCatalogCaches();
435474
RelationCacheInvalidate();
475+
476+
for (i = 0; i < cache_callback_count; i++)
477+
{
478+
struct CACHECALLBACK *ccitem = cache_callback_list + i;
479+
480+
(*ccitem->function) (ccitem->arg, InvalidOid);
481+
}
436482
}
437483

438484
/*
@@ -640,3 +686,51 @@ CacheInvalidateRelcache(Oid relationId)
640686
/* See KLUGE ALERT in PrepareForTupleInvalidation */
641687
RegisterRelcacheInvalidation(MyDatabaseId, relationId);
642688
}
689+
690+
/*
691+
* CacheRegisterSyscacheCallback
692+
* Register the specified function to be called for all future
693+
* invalidation events in the specified cache.
694+
*
695+
* NOTE: currently, the OID argument to the callback routine is not
696+
* provided for syscache callbacks; the routine doesn't really get any
697+
* useful info as to exactly what changed. It should treat every call
698+
* as a "cache flush" request.
699+
*/
700+
void
701+
CacheRegisterSyscacheCallback(int cacheid,
702+
CacheCallbackFunction func,
703+
Datum arg)
704+
{
705+
if (cache_callback_count >= MAX_CACHE_CALLBACKS)
706+
elog(FATAL, "Out of cache_callback_list slots");
707+
708+
cache_callback_list[cache_callback_count].id = cacheid;
709+
cache_callback_list[cache_callback_count].function = func;
710+
cache_callback_list[cache_callback_count].arg = arg;
711+
712+
++cache_callback_count;
713+
}
714+
715+
/*
716+
* CacheRegisterRelcacheCallback
717+
* Register the specified function to be called for all future
718+
* relcache invalidation events. The OID of the relation being
719+
* invalidated will be passed to the function.
720+
*
721+
* NOTE: InvalidOid will be passed if a cache reset request is received.
722+
* In this case the called routines should flush all cached state.
723+
*/
724+
void
725+
CacheRegisterRelcacheCallback(CacheCallbackFunction func,
726+
Datum arg)
727+
{
728+
if (cache_callback_count >= MAX_CACHE_CALLBACKS)
729+
elog(FATAL, "Out of cache_callback_list slots");
730+
731+
cache_callback_list[cache_callback_count].id = SHAREDINVALRELCACHE_ID;
732+
cache_callback_list[cache_callback_count].function = func;
733+
cache_callback_list[cache_callback_count].arg = arg;
734+
735+
++cache_callback_count;
736+
}

src/include/utils/inval.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: inval.h,v 1.24 2002/03/03 17:47:56 tgl Exp $
10+
* $Id: inval.h,v 1.25 2002/04/29 22:14:34 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -17,6 +17,9 @@
1717
#include "access/htup.h"
1818

1919

20+
typedef void (*CacheCallbackFunction) (Datum arg, Oid relid);
21+
22+
2023
extern void AcceptInvalidationMessages(void);
2124

2225
extern void AtEOXactInvalidationMessages(bool isCommit);
@@ -27,4 +30,11 @@ extern void CacheInvalidateHeapTuple(Relation relation, HeapTuple tuple);
2730

2831
extern void CacheInvalidateRelcache(Oid relationId);
2932

33+
extern void CacheRegisterSyscacheCallback(int cacheid,
34+
CacheCallbackFunction func,
35+
Datum arg);
36+
37+
extern void CacheRegisterRelcacheCallback(CacheCallbackFunction func,
38+
Datum arg);
39+
3040
#endif /* INVAL_H */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy