forked from timescale/pg_influx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cache.c
75 lines (63 loc) · 1.83 KB
/
cache.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "cache.h"
#include <postgres.h>
#include <utils/inval.h>
#include <utils/lsyscache.h>
#include <utils/rel.h>
/**
* Hash table with prepared inserts for relations.
*
* There is one entry for each relation that has been inserted into.
*/
static HTAB *InsertCache = NULL;
/**
* Initialize the cache.
*/
void InitInsertCache(void) {
HASHCTL hash_ctl;
memset(&hash_ctl, 0, sizeof(hash_ctl));
hash_ctl.keysize = sizeof(Oid);
hash_ctl.entrysize = sizeof(PreparedInsertData);
/* The initial size was arbitrarily picked. Most other usage of
* hash_create in the PostgreSQL code uses 128, so we do the same
* here. */
InsertCache =
hash_create("Prepared Inserts", 128, &hash_ctl, HASH_ELEM | HASH_BLOBS);
}
/**
* Find an existing entry for the given relation, or insert a new one.
*
* @param rel[in] Relation for the entry.
* @param precord[out] Pointer to variable for record.
* @retval true Existing entry was found.
* @retval false Inserted a new entry.
*/
bool FindOrAllocEntry(Relation rel, PreparedInsert *precord) {
const Oid relid = RelationGetRelid(rel);
bool found;
if (!InsertCache)
InitInsertCache();
*precord = hash_search(InsertCache, &relid, HASH_ENTER, &found);
return found;
}
/**
* Invalidate an insert cache entry.
*
* The cache entry is invalidated by just removing it. It will be
* re-created when it is again requested since it will not be found in
* the cache.
*
* @param arg[in] Not used
* @param relid[in] Relation id for relation that was invalidated
*/
void InsertCacheInvalCallback(Datum arg, Oid relid) {
if (InsertCache) {
bool found;
PreparedInsert record =
hash_search(InsertCache, &relid, HASH_REMOVE, &found);
if (found)
SPI_freeplan(record->pplan);
}
}
void CacheInit(void) {
CacheRegisterRelcacheCallback(InsertCacheInvalCallback, 0);
}