forked from postgrespro/aqo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.c
141 lines (124 loc) · 3.01 KB
/
utils.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
*******************************************************************************
*
* UTILITIES
*
*******************************************************************************
*
* Copyright (c) 2016-2021, Postgres Professional
*
* IDENTIFICATION
* aqo/utils.c
*
*/
#include "aqo.h"
/* TODO: get rid of those static vars */
static void *argsort_a;
static size_t argsort_es;
static int (*argsort_value_cmp) (const void *, const void *);
static int argsort_cmp(const void *a, const void *b);
/*
* Function for qsorting an integer arrays
*/
int
int_cmp(const void *a, const void *b)
{
if (*(int *) a < *(int *) b)
return -1;
else if (*(int *) a > *(int *) b)
return 1;
else
return 0;
}
/*
* Function for qsorting an double arrays
*/
int
double_cmp(const void *a, const void *b)
{
if (*(double *) a < *(double *) b)
return -1;
else if (*(double *) a > *(double *) b)
return 1;
else
return 0;
}
/*
* Compares elements for two given indexes
*/
int
argsort_cmp(const void *a, const void *b)
{
return (*argsort_value_cmp) ((char *) argsort_a +
*((int *) a) * argsort_es,
(char *) argsort_a +
*((int *) b) * argsort_es);
}
/*
* Returns array of indexes that makes given array sorted.
*/
int *
argsort(void *a, int n, size_t es, int (*cmp) (const void *, const void *))
{
int *idx = palloc(n * sizeof(*idx));
int i;
for (i = 0; i < n; ++i)
idx[i] = i;
argsort_value_cmp = cmp;
argsort_a = a;
argsort_es = es;
/* TODO: replace with qsort_arg() + see vars at the top */
qsort(idx, n, sizeof(*idx), argsort_cmp);
return idx;
}
/*
* Returns the inverse of given permutation.
*/
int *
inverse_permutation(int *idx, int n)
{
int *inv = palloc(n * sizeof(*inv));
int i;
for (i = 0; i < n; ++i)
inv[idx[i]] = i;
return inv;
}
/*
* Allocates empty QueryStat object.
*/
QueryStat *
palloc_query_stat(void)
{
QueryStat *res;
MemoryContext oldCxt;
oldCxt = MemoryContextSwitchTo(AQOMemoryContext);
res = palloc0(sizeof(QueryStat));
res->execution_time_with_aqo = palloc0(aqo_stat_size *
sizeof(res->execution_time_with_aqo[0]));
res->execution_time_without_aqo = palloc0(aqo_stat_size *
sizeof(res->execution_time_without_aqo[0]));
res->planning_time_with_aqo = palloc0(aqo_stat_size *
sizeof(res->planning_time_with_aqo[0]));
res->planning_time_without_aqo = palloc0(aqo_stat_size *
sizeof(res->planning_time_without_aqo[0]));
res->cardinality_error_with_aqo = palloc0(aqo_stat_size *
sizeof(res->cardinality_error_with_aqo[0]));
res->cardinality_error_without_aqo = palloc0(aqo_stat_size *
sizeof(res->cardinality_error_without_aqo[0]));
MemoryContextSwitchTo(oldCxt);
return res;
}
/*
* Frees QueryStat object.
*/
void
pfree_query_stat(QueryStat * stat)
{
pfree(stat->execution_time_with_aqo);
pfree(stat->execution_time_without_aqo);
pfree(stat->planning_time_with_aqo);
pfree(stat->planning_time_without_aqo);
pfree(stat->cardinality_error_with_aqo);
pfree(stat->cardinality_error_without_aqo);
pfree(stat);
}