-
Notifications
You must be signed in to change notification settings - Fork 56
/
selectivity_cache.c
111 lines (98 loc) · 2.3 KB
/
selectivity_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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
*******************************************************************************
*
* SELECTIVITY CACHE
*
* Stores the clause selectivity with the given relids for parametrized
* clauses, because otherwise it cannot be restored after query execution
* without PlannerInfo.
*
*******************************************************************************
*
* Copyright (c) 2016-2022, Postgres Professional
*
* IDENTIFICATION
* aqo/selectivity_cache.c
*
*/
#include "postgres.h"
#include "aqo.h"
typedef struct
{
int clause_hash;
int relid;
int global_relid;
double selectivity;
} Entry;
static List *objects = NIL;
/* Specific memory context for selectivity objects */
static MemoryContext AQOCacheSelectivity = NULL;
/*
* Stores the given selectivity for clause_hash, relid and global_relid
* of the clause.
*/
void
cache_selectivity(int clause_hash,
int relid,
int global_relid,
double selectivity)
{
ListCell *l;
Entry *cur_element;
MemoryContext old_ctx;
if (!AQOCacheSelectivity)
AQOCacheSelectivity = AllocSetContextCreate(AQOTopMemCtx,
"AQOCacheSelectivity",
ALLOCSET_DEFAULT_SIZES);
foreach(l, objects)
{
cur_element = (Entry *) lfirst(l);
if (cur_element->clause_hash == clause_hash &&
cur_element->relid == relid &&
cur_element->global_relid == global_relid)
{
return;
}
}
old_ctx = MemoryContextSwitchTo(AQOCacheSelectivity);
cur_element = palloc(sizeof(*cur_element));
cur_element->clause_hash = clause_hash;
cur_element->relid = relid;
cur_element->global_relid = global_relid;
cur_element->selectivity = selectivity;
objects = lappend(objects, cur_element);
MemoryContextSwitchTo(old_ctx);
}
/*
* Restores selectivity for given clause_hash and global_relid.
*/
double *
selectivity_cache_find_global_relid(int clause_hash, int global_relid)
{
ListCell *l;
Entry *cur_element;
foreach(l, objects)
{
cur_element = (Entry *) lfirst(l);
if (cur_element->clause_hash == clause_hash &&
cur_element->global_relid == global_relid)
{
return &(cur_element->selectivity);
}
}
return NULL;
}
/*
* Clears selectivity cache.
*/
void
selectivity_cache_clear(void)
{
if (!AQOCacheSelectivity)
{
Assert(objects == NIL);
return;
}
MemoryContextReset(AQOCacheSelectivity);
objects = NIL;
}