PostgreSQL Source Code git master
ginbulk.c File Reference
#include "postgres.h"
#include <limits.h>
#include "access/gin_private.h"
#include "utils/datum.h"
#include "utils/memutils.h"
Include dependency graph for ginbulk.c:

Go to the source code of this file.

Macros

#define DEF_NENTRY   2048 /* GinEntryAccumulator allocation quantum */
 
#define DEF_NPTR   5 /* ItemPointer initial allocation quantum */
 

Functions

static void ginCombineData (RBTNode *existing, const RBTNode *newdata, void *arg)
 
static int cmpEntryAccumulator (const RBTNode *a, const RBTNode *b, void *arg)
 
static RBTNodeginAllocEntryAccumulator (void *arg)
 
void ginInitBA (BuildAccumulator *accum)
 
static Datum getDatumCopy (BuildAccumulator *accum, OffsetNumber attnum, Datum value)
 
static void ginInsertBAEntry (BuildAccumulator *accum, ItemPointer heapptr, OffsetNumber attnum, Datum key, GinNullCategory category)
 
void ginInsertBAEntries (BuildAccumulator *accum, ItemPointer heapptr, OffsetNumber attnum, Datum *entries, GinNullCategory *categories, int32 nentries)
 
static int qsortCompareItemPointers (const void *a, const void *b)
 
void ginBeginBAScan (BuildAccumulator *accum)
 
ItemPointerDataginGetBAEntry (BuildAccumulator *accum, OffsetNumber *attnum, Datum *key, GinNullCategory *category, uint32 *n)
 

Macro Definition Documentation

◆ DEF_NENTRY

#define DEF_NENTRY   2048 /* GinEntryAccumulator allocation quantum */

Definition at line 24 of file ginbulk.c.

◆ DEF_NPTR

#define DEF_NPTR   5 /* ItemPointer initial allocation quantum */

Definition at line 25 of file ginbulk.c.

Function Documentation

◆ cmpEntryAccumulator()

static int cmpEntryAccumulator ( const RBTNode a,
const RBTNode b,
void *  arg 
)
static

Definition at line 72 of file ginbulk.c.

73{
74 const GinEntryAccumulator *ea = (const GinEntryAccumulator *) a;
75 const GinEntryAccumulator *eb = (const GinEntryAccumulator *) b;
77
78 return ginCompareAttEntries(accum->ginstate,
79 ea->attnum, ea->key, ea->category,
80 eb->attnum, eb->key, eb->category);
81}
int ginCompareAttEntries(GinState *ginstate, OffsetNumber attnuma, Datum a, GinNullCategory categorya, OffsetNumber attnumb, Datum b, GinNullCategory categoryb)
Definition: ginutil.c:415
int b
Definition: isn.c:71
int a
Definition: isn.c:70
void * arg
GinState * ginstate
Definition: gin_private.h:441
OffsetNumber attnum
Definition: gin_private.h:432
GinNullCategory category
Definition: gin_private.h:431

References a, arg, GinEntryAccumulator::attnum, b, GinEntryAccumulator::category, ginCompareAttEntries(), BuildAccumulator::ginstate, and GinEntryAccumulator::key.

Referenced by ginInitBA().

◆ getDatumCopy()

static Datum getDatumCopy ( BuildAccumulator accum,
OffsetNumber  attnum,
Datum  value 
)
static

Definition at line 128 of file ginbulk.c.

129{
130 CompactAttribute *att;
131 Datum res;
132
134 if (att->attbyval)
135 res = value;
136 else
137 {
138 res = datumCopy(value, false, att->attlen);
140 }
141 return res;
142}
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
static struct @165 value
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:721
int16 attnum
Definition: pg_attribute.h:74
uintptr_t Datum
Definition: postgres.h:69
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
int16 attlen
Definition: tupdesc.h:71
TupleDesc origTupdesc
Definition: gin_private.h:73
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:169

References BuildAccumulator::allocatedMemory, CompactAttribute::attbyval, CompactAttribute::attlen, attnum, datumCopy(), DatumGetPointer(), GetMemoryChunkSpace(), BuildAccumulator::ginstate, GinState::origTupdesc, TupleDescCompactAttr(), and value.

Referenced by ginInsertBAEntry().

◆ ginAllocEntryAccumulator()

static RBTNode * ginAllocEntryAccumulator ( void *  arg)
static

Definition at line 85 of file ginbulk.c.

86{
89
90 /*
91 * Allocate memory by rather big chunks to decrease overhead. We have no
92 * need to reclaim RBTNodes individually, so this costs nothing.
93 */
94 if (accum->entryallocator == NULL || accum->eas_used >= DEF_NENTRY)
95 {
98 accum->eas_used = 0;
99 }
100
101 /* Allocate new RBTNode from current chunk */
102 ea = accum->entryallocator + accum->eas_used;
103 accum->eas_used++;
104
105 return (RBTNode *) ea;
106}
#define DEF_NENTRY
Definition: ginbulk.c:24
void * palloc(Size size)
Definition: mcxt.c:1317
GinEntryAccumulator * entryallocator
Definition: gin_private.h:443
Definition: rbtree.h:24

References BuildAccumulator::allocatedMemory, arg, DEF_NENTRY, BuildAccumulator::eas_used, BuildAccumulator::entryallocator, GetMemoryChunkSpace(), and palloc().

Referenced by ginInitBA().

◆ ginBeginBAScan()

void ginBeginBAScan ( BuildAccumulator accum)

Definition at line 257 of file ginbulk.c.

258{
260}
void rbt_begin_iterate(RBTree *rbt, RBTOrderControl ctrl, RBTreeIterator *iter)
Definition: rbtree.c:802
@ LeftRightWalk
Definition: rbtree.h:37
RBTreeIterator tree_walk
Definition: gin_private.h:446

References LeftRightWalk, rbt_begin_iterate(), BuildAccumulator::tree, and BuildAccumulator::tree_walk.

Referenced by ginbuild(), ginBuildCallback(), ginFlushBuildState(), and ginInsertCleanup().

◆ ginCombineData()

static void ginCombineData ( RBTNode existing,
const RBTNode newdata,
void *  arg 
)
static

Definition at line 30 of file ginbulk.c.

31{
33 const GinEntryAccumulator *en = (const GinEntryAccumulator *) newdata;
35
36 /*
37 * Note this code assumes that newdata contains only one itempointer.
38 */
39 if (eo->count >= eo->maxcount)
40 {
41 if (eo->maxcount > INT_MAX)
43 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
44 errmsg("posting list is too long"),
45 errhint("Reduce \"maintenance_work_mem\".")));
46
48 eo->maxcount *= 2;
49 eo->list = (ItemPointerData *)
50 repalloc_huge(eo->list, sizeof(ItemPointerData) * eo->maxcount);
52 }
53
54 /* If item pointers are not ordered, they will need to be sorted later */
55 if (eo->shouldSort == false)
56 {
57 int res;
58
59 res = ginCompareItemPointers(eo->list + eo->count - 1, en->list);
60 Assert(res != 0);
61
62 if (res > 0)
63 eo->shouldSort = true;
64 }
65
66 eo->list[eo->count] = en->list[0];
67 eo->count++;
68}
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
static int ginCompareItemPointers(ItemPointer a, ItemPointer b)
Definition: gin_private.h:496
Assert(PointerIsAligned(start, uint64))
void * repalloc_huge(void *pointer, Size size)
Definition: mcxt.c:1675
ItemPointerData * list
Definition: gin_private.h:434

References BuildAccumulator::allocatedMemory, arg, Assert(), GinEntryAccumulator::count, ereport, errcode(), errhint(), errmsg(), ERROR, GetMemoryChunkSpace(), ginCompareItemPointers(), GinEntryAccumulator::list, GinEntryAccumulator::maxcount, repalloc_huge(), and GinEntryAccumulator::shouldSort.

Referenced by ginInitBA().

◆ ginGetBAEntry()

ItemPointerData * ginGetBAEntry ( BuildAccumulator accum,
OffsetNumber attnum,
Datum key,
GinNullCategory category,
uint32 n 
)

Definition at line 268 of file ginbulk.c.

271{
272 GinEntryAccumulator *entry;
274
275 entry = (GinEntryAccumulator *) rbt_iterate(&accum->tree_walk);
276
277 if (entry == NULL)
278 return NULL; /* no more entries */
279
280 *attnum = entry->attnum;
281 *key = entry->key;
282 *category = entry->category;
283 list = entry->list;
284 *n = entry->count;
285
286 Assert(list != NULL && entry->count > 0);
287
288 if (entry->shouldSort && entry->count > 1)
289 qsort(list, entry->count, sizeof(ItemPointerData),
291
292 return list;
293}
static int qsortCompareItemPointers(const void *a, const void *b)
Definition: ginbulk.c:246
#define qsort(a, b, c, d)
Definition: port.h:475
RBTNode * rbt_iterate(RBTreeIterator *iter)
Definition: rbtree.c:826

References Assert(), GinEntryAccumulator::attnum, attnum, GinEntryAccumulator::category, GinEntryAccumulator::count, GinEntryAccumulator::key, sort-test::key, GinEntryAccumulator::list, sort-test::list, qsort, qsortCompareItemPointers(), rbt_iterate(), GinEntryAccumulator::shouldSort, and BuildAccumulator::tree_walk.

Referenced by ginbuild(), ginBuildCallback(), ginFlushBuildState(), and ginInsertCleanup().

◆ ginInitBA()

void ginInitBA ( BuildAccumulator accum)

Definition at line 109 of file ginbulk.c.

110{
111 /* accum->ginstate is intentionally not set here */
112 accum->allocatedMemory = 0;
113 accum->entryallocator = NULL;
114 accum->eas_used = 0;
115 accum->tree = rbt_create(sizeof(GinEntryAccumulator),
119 NULL, /* no freefunc needed */
120 accum);
121}
static void ginCombineData(RBTNode *existing, const RBTNode *newdata, void *arg)
Definition: ginbulk.c:30
static RBTNode * ginAllocEntryAccumulator(void *arg)
Definition: ginbulk.c:85
static int cmpEntryAccumulator(const RBTNode *a, const RBTNode *b, void *arg)
Definition: ginbulk.c:72
RBTree * rbt_create(Size node_size, rbt_comparator comparator, rbt_combiner combiner, rbt_allocfunc allocfunc, rbt_freefunc freefunc, void *arg)
Definition: rbtree.c:102

References BuildAccumulator::allocatedMemory, cmpEntryAccumulator(), BuildAccumulator::eas_used, BuildAccumulator::entryallocator, ginAllocEntryAccumulator(), ginCombineData(), rbt_create(), and BuildAccumulator::tree.

Referenced by _gin_parallel_build_main(), ginbuild(), ginBuildCallback(), ginFlushBuildState(), and ginInsertCleanup().

◆ ginInsertBAEntries()

void ginInsertBAEntries ( BuildAccumulator accum,
ItemPointer  heapptr,
OffsetNumber  attnum,
Datum entries,
GinNullCategory categories,
int32  nentries 
)

Definition at line 210 of file ginbulk.c.

214{
215 uint32 step = nentries;
216
217 if (nentries <= 0)
218 return;
219
221
222 /*
223 * step will contain largest power of 2 and <= nentries
224 */
225 step |= (step >> 1);
226 step |= (step >> 2);
227 step |= (step >> 4);
228 step |= (step >> 8);
229 step |= (step >> 16);
230 step >>= 1;
231 step++;
232
233 while (step > 0)
234 {
235 int i;
236
237 for (i = step - 1; i < nentries && i >= 0; i += step << 1 /* *2 */ )
238 ginInsertBAEntry(accum, heapptr, attnum,
239 entries[i], categories[i]);
240
241 step >>= 1; /* /2 */
242 }
243}
uint32_t uint32
Definition: c.h:502
static void ginInsertBAEntry(BuildAccumulator *accum, ItemPointer heapptr, OffsetNumber attnum, Datum key, GinNullCategory category)
Definition: ginbulk.c:148
int i
Definition: isn.c:74
static bool ItemPointerIsValid(const ItemPointerData *pointer)
Definition: itemptr.h:83
#define FirstOffsetNumber
Definition: off.h:27

References Assert(), attnum, FirstOffsetNumber, ginInsertBAEntry(), i, and ItemPointerIsValid().

Referenced by ginHeapTupleBulkInsert(), and processPendingPage().

◆ ginInsertBAEntry()

static void ginInsertBAEntry ( BuildAccumulator accum,
ItemPointer  heapptr,
OffsetNumber  attnum,
Datum  key,
GinNullCategory  category 
)
static

Definition at line 148 of file ginbulk.c.

151{
154 bool isNew;
155
156 /*
157 * For the moment, fill only the fields of eatmp that will be looked at by
158 * cmpEntryAccumulator or ginCombineData.
159 */
160 eatmp.attnum = attnum;
161 eatmp.key = key;
162 eatmp.category = category;
163 /* temporarily set up single-entry itempointer list */
164 eatmp.list = heapptr;
165
166 ea = (GinEntryAccumulator *) rbt_insert(accum->tree, (RBTNode *) &eatmp,
167 &isNew);
168
169 if (isNew)
170 {
171 /*
172 * Finish initializing new tree entry, including making permanent
173 * copies of the datum (if it's not null) and itempointer.
174 */
175 if (category == GIN_CAT_NORM_KEY)
176 ea->key = getDatumCopy(accum, attnum, key);
177 ea->maxcount = DEF_NPTR;
178 ea->count = 1;
179 ea->shouldSort = false;
180 ea->list =
182 ea->list[0] = *heapptr;
184 }
185 else
186 {
187 /*
188 * ginCombineData did everything needed.
189 */
190 }
191}
#define GIN_CAT_NORM_KEY
Definition: ginblock.h:208
#define DEF_NPTR
Definition: ginbulk.c:25
static Datum getDatumCopy(BuildAccumulator *accum, OffsetNumber attnum, Datum value)
Definition: ginbulk.c:128
RBTNode * rbt_insert(RBTree *rbt, const RBTNode *data, bool *isNew)
Definition: rbtree.c:453

References BuildAccumulator::allocatedMemory, GinEntryAccumulator::attnum, attnum, GinEntryAccumulator::category, GinEntryAccumulator::count, DEF_NPTR, getDatumCopy(), GetMemoryChunkSpace(), GIN_CAT_NORM_KEY, GinEntryAccumulator::key, sort-test::key, GinEntryAccumulator::list, GinEntryAccumulator::maxcount, palloc(), rbt_insert(), GinEntryAccumulator::shouldSort, and BuildAccumulator::tree.

Referenced by ginInsertBAEntries().

◆ qsortCompareItemPointers()

static int qsortCompareItemPointers ( const void *  a,
const void *  b 
)
static

Definition at line 246 of file ginbulk.c.

247{
249
250 /* Assert that there are no equal item pointers being sorted */
251 Assert(res != 0);
252 return res;
253}

References a, Assert(), b, and ginCompareItemPointers().

Referenced by ginGetBAEntry().