PostgreSQL Source Code  git master
tidstore.h File Reference
#include "storage/itemptr.h"
#include "utils/dsa.h"
Include dependency graph for tidstore.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  TidStoreIterResult
 

Typedefs

typedef struct TidStore TidStore
 
typedef struct TidStoreIter TidStoreIter
 
typedef struct TidStoreIterResult TidStoreIterResult
 

Functions

TidStoreTidStoreCreateLocal (size_t max_bytes, bool insert_only)
 
TidStoreTidStoreCreateShared (size_t max_bytes, int tranche_id)
 
TidStoreTidStoreAttach (dsa_handle area_handle, dsa_pointer handle)
 
void TidStoreDetach (TidStore *ts)
 
void TidStoreLockExclusive (TidStore *ts)
 
void TidStoreLockShare (TidStore *ts)
 
void TidStoreUnlock (TidStore *ts)
 
void TidStoreDestroy (TidStore *ts)
 
void TidStoreSetBlockOffsets (TidStore *ts, BlockNumber blkno, OffsetNumber *offsets, int num_offsets)
 
bool TidStoreIsMember (TidStore *ts, ItemPointer tid)
 
TidStoreIterTidStoreBeginIterate (TidStore *ts)
 
TidStoreIterResultTidStoreIterateNext (TidStoreIter *iter)
 
void TidStoreEndIterate (TidStoreIter *iter)
 
size_t TidStoreMemoryUsage (TidStore *ts)
 
dsa_pointer TidStoreGetHandle (TidStore *ts)
 
dsa_areaTidStoreGetDSA (TidStore *ts)
 

Typedef Documentation

◆ TidStore

typedef struct TidStore TidStore

Definition at line 1 of file tidstore.h.

◆ TidStoreIter

typedef struct TidStoreIter TidStoreIter

Definition at line 1 of file tidstore.h.

◆ TidStoreIterResult

Function Documentation

◆ TidStoreAttach()

TidStore* TidStoreAttach ( dsa_handle  area_handle,
dsa_pointer  handle 
)

Definition at line 255 of file tidstore.c.

256 {
257  TidStore *ts;
258  dsa_area *area;
259 
260  Assert(area_handle != DSA_HANDLE_INVALID);
261  Assert(DsaPointerIsValid(handle));
262 
263  /* create per-backend state */
264  ts = palloc0(sizeof(TidStore));
265 
266  area = dsa_attach(area_handle);
267 
268  /* Find the shared the shared radix tree */
269  ts->tree.shared = shared_ts_attach(area, handle);
270  ts->area = area;
271 
272  return ts;
273 }
#define Assert(condition)
Definition: c.h:858
dsa_area * dsa_attach(dsa_handle handle)
Definition: dsa.c:510
#define DSA_HANDLE_INVALID
Definition: dsa.h:139
#define DsaPointerIsValid(x)
Definition: dsa.h:106
void * palloc0(Size size)
Definition: mcxt.c:1346
dsa_area * area
Definition: tidstore.c:130
shared_ts_radix_tree * shared
Definition: tidstore.c:126
union TidStore::@13 tree
Definition: dsa.c:348

References TidStore::area, Assert, dsa_attach(), DSA_HANDLE_INVALID, DsaPointerIsValid, palloc0(), TidStore::shared, and TidStore::tree.

Referenced by parallel_vacuum_main().

◆ TidStoreBeginIterate()

TidStoreIter* TidStoreBeginIterate ( TidStore ts)

Definition at line 482 of file tidstore.c.

483 {
484  TidStoreIter *iter;
485 
486  iter = palloc0(sizeof(TidStoreIter));
487  iter->ts = ts;
488 
489  /*
490  * We start with an array large enough to contain at least the offsets
491  * from one completely full bitmap element.
492  */
494  iter->output.offsets = palloc(sizeof(OffsetNumber) * iter->output.max_offset);
495 
496  if (TidStoreIsShared(ts))
497  iter->tree_iter.shared = shared_ts_begin_iterate(ts->tree.shared);
498  else
499  iter->tree_iter.local = local_ts_begin_iterate(ts->tree.local);
500 
501  return iter;
502 }
#define BITS_PER_BITMAPWORD
Definition: bitmapset.h:43
void * palloc(Size size)
Definition: mcxt.c:1316
uint16 OffsetNumber
Definition: off.h:24
OffsetNumber * offsets
Definition: tidstore.h:29
shared_ts_iter * shared
Definition: tidstore.c:142
local_ts_iter * local
Definition: tidstore.c:143
TidStore * ts
Definition: tidstore.c:137
TidStoreIterResult output
Definition: tidstore.c:147
union TidStoreIter::@14 tree_iter
local_ts_radix_tree * local
Definition: tidstore.c:125
#define TidStoreIsShared(ts)
Definition: tidstore.c:132

References BITS_PER_BITMAPWORD, TidStore::local, TidStoreIter::local, TidStoreIterResult::max_offset, TidStoreIterResult::offsets, TidStoreIter::output, palloc(), palloc0(), TidStore::shared, TidStoreIter::shared, TidStoreIsShared, TidStore::tree, TidStoreIter::tree_iter, and TidStoreIter::ts.

Referenced by check_set_block_offsets(), and lazy_vacuum_heap_rel().

◆ TidStoreCreateLocal()

TidStore* TidStoreCreateLocal ( size_t  max_bytes,
bool  insert_only 
)

Definition at line 165 of file tidstore.c.

166 {
167  TidStore *ts;
168  size_t initBlockSize = ALLOCSET_DEFAULT_INITSIZE;
169  size_t minContextSize = ALLOCSET_DEFAULT_MINSIZE;
170  size_t maxBlockSize = ALLOCSET_DEFAULT_MAXSIZE;
171 
172  ts = palloc0(sizeof(TidStore));
174 
175  /* choose the maxBlockSize to be no larger than 1/16 of max_bytes */
176  while (16 * maxBlockSize > max_bytes)
177  maxBlockSize >>= 1;
178 
179  if (maxBlockSize < ALLOCSET_DEFAULT_INITSIZE)
180  maxBlockSize = ALLOCSET_DEFAULT_INITSIZE;
181 
182  /* Create a memory context for the TID storage */
183  if (insert_only)
184  {
186  "TID storage",
187  minContextSize,
188  initBlockSize,
189  maxBlockSize);
190  }
191  else
192  {
194  "TID storage",
195  minContextSize,
196  initBlockSize,
197  maxBlockSize);
198  }
199 
200  ts->tree.local = local_ts_create(ts->rt_context);
201 
202  return ts;
203 }
MemoryContext BumpContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: bump.c:131
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_MAXSIZE
Definition: memutils.h:159
#define ALLOCSET_DEFAULT_MINSIZE
Definition: memutils.h:157
#define ALLOCSET_DEFAULT_INITSIZE
Definition: memutils.h:158
MemoryContext context
Definition: tidstore.c:117
MemoryContext rt_context
Definition: tidstore.c:120

References ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, AllocSetContextCreate, BumpContextCreate(), TidStore::context, CurrentMemoryContext, TidStore::local, palloc0(), TidStore::rt_context, and TidStore::tree.

Referenced by dead_items_alloc(), dead_items_reset(), and test_create().

◆ TidStoreCreateShared()

TidStore* TidStoreCreateShared ( size_t  max_bytes,
int  tranche_id 
)

Definition at line 213 of file tidstore.c.

214 {
215  TidStore *ts;
216  dsa_area *area;
217  size_t dsa_init_size = DSA_DEFAULT_INIT_SEGMENT_SIZE;
218  size_t dsa_max_size = DSA_MAX_SEGMENT_SIZE;
219 
220  ts = palloc0(sizeof(TidStore));
222 
224  "TID storage meta data",
226 
227  /*
228  * Choose the initial and maximum DSA segment sizes to be no longer than
229  * 1/8 of max_bytes.
230  */
231  while (8 * dsa_max_size > max_bytes)
232  dsa_max_size >>= 1;
233 
234  if (dsa_max_size < DSA_MIN_SEGMENT_SIZE)
235  dsa_max_size = DSA_MIN_SEGMENT_SIZE;
236 
237  if (dsa_init_size > dsa_max_size)
238  dsa_init_size = dsa_max_size;
239 
240  area = dsa_create_ext(tranche_id, dsa_init_size, dsa_max_size);
241  ts->tree.shared = shared_ts_create(ts->rt_context, area,
242  tranche_id);
243  ts->area = area;
244 
245  return ts;
246 }
dsa_area * dsa_create_ext(int tranche_id, size_t init_segment_size, size_t max_segment_size)
Definition: dsa.c:421
#define DSA_MIN_SEGMENT_SIZE
Definition: dsa.h:100
#define DSA_DEFAULT_INIT_SEGMENT_SIZE
Definition: dsa.h:97
#define DSA_MAX_SEGMENT_SIZE
Definition: dsa.h:103
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:170

References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, TidStore::area, TidStore::context, CurrentMemoryContext, dsa_create_ext(), DSA_DEFAULT_INIT_SEGMENT_SIZE, DSA_MAX_SEGMENT_SIZE, DSA_MIN_SEGMENT_SIZE, palloc0(), TidStore::rt_context, TidStore::shared, and TidStore::tree.

Referenced by parallel_vacuum_init(), parallel_vacuum_reset_dead_items(), and test_create().

◆ TidStoreDestroy()

void TidStoreDestroy ( TidStore ts)

Definition at line 328 of file tidstore.c.

329 {
330  /* Destroy underlying radix tree */
331  if (TidStoreIsShared(ts))
332  {
333  shared_ts_free(ts->tree.shared);
334 
335  dsa_detach(ts->area);
336  }
337  else
338  local_ts_free(ts->tree.local);
339 
341 
342  pfree(ts);
343 }
void dsa_detach(dsa_area *area)
Definition: dsa.c:1952
void pfree(void *pointer)
Definition: mcxt.c:1520
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454

References TidStore::area, dsa_detach(), TidStore::local, MemoryContextDelete(), pfree(), TidStore::rt_context, TidStore::shared, TidStoreIsShared, and TidStore::tree.

Referenced by dead_items_reset(), parallel_vacuum_end(), parallel_vacuum_reset_dead_items(), and test_destroy().

◆ TidStoreDetach()

void TidStoreDetach ( TidStore ts)

Definition at line 280 of file tidstore.c.

281 {
283 
284  shared_ts_detach(ts->tree.shared);
285  dsa_detach(ts->area);
286 
287  pfree(ts);
288 }

References TidStore::area, Assert, dsa_detach(), pfree(), TidStore::shared, TidStoreIsShared, and TidStore::tree.

Referenced by parallel_vacuum_main().

◆ TidStoreEndIterate()

void TidStoreEndIterate ( TidStoreIter iter)

Definition at line 536 of file tidstore.c.

537 {
538  if (TidStoreIsShared(iter->ts))
539  shared_ts_end_iterate(iter->tree_iter.shared);
540  else
541  local_ts_end_iterate(iter->tree_iter.local);
542 
543  pfree(iter->output.offsets);
544  pfree(iter);
545 }

References TidStoreIter::local, TidStoreIterResult::offsets, TidStoreIter::output, pfree(), TidStoreIter::shared, TidStoreIsShared, TidStoreIter::tree_iter, and TidStoreIter::ts.

Referenced by check_set_block_offsets(), and lazy_vacuum_heap_rel().

◆ TidStoreGetDSA()

dsa_area* TidStoreGetDSA ( TidStore ts)

Definition at line 563 of file tidstore.c.

564 {
566 
567  return ts->area;
568 }

References TidStore::area, Assert, and TidStoreIsShared.

Referenced by parallel_vacuum_init(), parallel_vacuum_reset_dead_items(), and test_create().

◆ TidStoreGetHandle()

dsa_pointer TidStoreGetHandle ( TidStore ts)

Definition at line 571 of file tidstore.c.

572 {
574 
575  return (dsa_pointer) shared_ts_get_handle(ts->tree.shared);
576 }
uint64 dsa_pointer
Definition: dsa.h:62

References Assert, TidStore::shared, TidStoreIsShared, and TidStore::tree.

Referenced by parallel_vacuum_init(), and parallel_vacuum_reset_dead_items().

◆ TidStoreIsMember()

bool TidStoreIsMember ( TidStore ts,
ItemPointer  tid 
)

Definition at line 432 of file tidstore.c.

433 {
434  int wordnum;
435  int bitnum;
436  BlocktableEntry *page;
439 
440  if (TidStoreIsShared(ts))
441  page = shared_ts_find(ts->tree.shared, blk);
442  else
443  page = local_ts_find(ts->tree.local, blk);
444 
445  /* no entry for the blk */
446  if (page == NULL)
447  return false;
448 
449  if (page->header.nwords == 0)
450  {
451  /* we have offsets in the header */
452  for (int i = 0; i < NUM_FULL_OFFSETS; i++)
453  {
454  if (page->header.full_offsets[i] == off)
455  return true;
456  }
457  return false;
458  }
459  else
460  {
461  wordnum = WORDNUM(off);
462  bitnum = BITNUM(off);
463 
464  /* no bitmap for the off */
465  if (wordnum >= page->header.nwords)
466  return false;
467 
468  return (page->words[wordnum] & ((bitmapword) 1 << bitnum)) != 0;
469  }
470 }
uint32 bitmapword
Definition: bitmapset.h:44
uint32 BlockNumber
Definition: block.h:31
int i
Definition: isn.c:73
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
Definition: itemptr.h:124
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
Definition: itemptr.h:103
bitmapword words[FLEXIBLE_ARRAY_MEMBER]
Definition: tidstore.c:76
struct BlocktableEntry::@12 header
OffsetNumber full_offsets[NUM_FULL_OFFSETS]
Definition: tidstore.c:63
#define NUM_FULL_OFFSETS
Definition: tidstore.c:38
#define WORDNUM(x)
Definition: tidstore.c:31
#define BITNUM(x)
Definition: tidstore.c:32

References BITNUM, BlocktableEntry::full_offsets, BlocktableEntry::header, i, ItemPointerGetBlockNumber(), ItemPointerGetOffsetNumber(), TidStore::local, NUM_FULL_OFFSETS, BlocktableEntry::nwords, TidStore::shared, TidStoreIsShared, TidStore::tree, WORDNUM, and BlocktableEntry::words.

Referenced by check_set_block_offsets(), and vac_tid_reaped().

◆ TidStoreIterateNext()

TidStoreIterResult* TidStoreIterateNext ( TidStoreIter iter)

Definition at line 511 of file tidstore.c.

512 {
513  uint64 key;
514  BlocktableEntry *page;
515 
516  if (TidStoreIsShared(iter->ts))
517  page = shared_ts_iterate_next(iter->tree_iter.shared, &key);
518  else
519  page = local_ts_iterate_next(iter->tree_iter.local, &key);
520 
521  if (page == NULL)
522  return NULL;
523 
524  /* Collect TIDs from the key-value pair */
526 
527  return &(iter->output);
528 }
static void tidstore_iter_extract_tids(TidStoreIter *iter, BlockNumber blkno, BlocktableEntry *page)
Definition: tidstore.c:580

References sort-test::key, TidStoreIter::local, TidStoreIter::output, TidStoreIter::shared, tidstore_iter_extract_tids(), TidStoreIsShared, TidStoreIter::tree_iter, and TidStoreIter::ts.

Referenced by check_set_block_offsets(), and lazy_vacuum_heap_rel().

◆ TidStoreLockExclusive()

void TidStoreLockExclusive ( TidStore ts)

Definition at line 298 of file tidstore.c.

299 {
300  if (TidStoreIsShared(ts))
301  shared_ts_lock_exclusive(ts->tree.shared);
302 }

References TidStore::shared, TidStoreIsShared, and TidStore::tree.

Referenced by do_set_block_offsets().

◆ TidStoreLockShare()

void TidStoreLockShare ( TidStore ts)

Definition at line 305 of file tidstore.c.

306 {
307  if (TidStoreIsShared(ts))
308  shared_ts_lock_share(ts->tree.shared);
309 }

References TidStore::shared, TidStoreIsShared, and TidStore::tree.

Referenced by check_set_block_offsets().

◆ TidStoreMemoryUsage()

size_t TidStoreMemoryUsage ( TidStore ts)

Definition at line 551 of file tidstore.c.

552 {
553  if (TidStoreIsShared(ts))
554  return shared_ts_memory_usage(ts->tree.shared);
555  else
556  return local_ts_memory_usage(ts->tree.local);
557 }

References TidStore::local, TidStore::shared, TidStoreIsShared, and TidStore::tree.

Referenced by dead_items_add(), lazy_scan_heap(), lazy_vacuum(), test_create(), and test_is_full().

◆ TidStoreSetBlockOffsets()

void TidStoreSetBlockOffsets ( TidStore ts,
BlockNumber  blkno,
OffsetNumber offsets,
int  num_offsets 
)

Definition at line 356 of file tidstore.c.

358 {
359  union
360  {
362  BlocktableEntry force_align_entry;
363  } data;
364  BlocktableEntry *page = (BlocktableEntry *) data.data;
366  int wordnum;
367  int next_word_threshold;
368  int idx = 0;
369 
370  Assert(num_offsets > 0);
371 
372  /* Check if the given offset numbers are ordered */
373  for (int i = 1; i < num_offsets; i++)
374  Assert(offsets[i] > offsets[i - 1]);
375 
376  memset(page, 0, offsetof(BlocktableEntry, words));
377 
378  if (num_offsets <= NUM_FULL_OFFSETS)
379  {
380  for (int i = 0; i < num_offsets; i++)
381  {
382  OffsetNumber off = offsets[i];
383 
384  /* safety check to ensure we don't overrun bit array bounds */
385  if (off == InvalidOffsetNumber || off > MAX_OFFSET_IN_BITMAP)
386  elog(ERROR, "tuple offset out of range: %u", off);
387 
388  page->header.full_offsets[i] = off;
389  }
390 
391  page->header.nwords = 0;
392  }
393  else
394  {
395  for (wordnum = 0, next_word_threshold = BITS_PER_BITMAPWORD;
396  wordnum <= WORDNUM(offsets[num_offsets - 1]);
397  wordnum++, next_word_threshold += BITS_PER_BITMAPWORD)
398  {
399  word = 0;
400 
401  while (idx < num_offsets)
402  {
403  OffsetNumber off = offsets[idx];
404 
405  /* safety check to ensure we don't overrun bit array bounds */
406  if (off == InvalidOffsetNumber || off > MAX_OFFSET_IN_BITMAP)
407  elog(ERROR, "tuple offset out of range: %u", off);
408 
409  if (off >= next_word_threshold)
410  break;
411 
412  word |= ((bitmapword) 1 << BITNUM(off));
413  idx++;
414  }
415 
416  /* write out offset bitmap for this wordnum */
417  page->words[wordnum] = word;
418  }
419 
420  page->header.nwords = wordnum;
421  Assert(page->header.nwords == WORDS_PER_PAGE(offsets[num_offsets - 1]));
422  }
423 
424  if (TidStoreIsShared(ts))
425  shared_ts_set(ts->tree.shared, blkno, page);
426  else
427  local_ts_set(ts->tree.local, blkno, page);
428 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define InvalidOffsetNumber
Definition: off.h:26
const void * data
static void word(struct vars *v, int dir, struct state *lp, struct state *rp)
Definition: regcomp.c:1474
#define WORDS_PER_PAGE(n)
Definition: tidstore.c:35
#define MAX_OFFSET_IN_BITMAP
Definition: tidstore.c:84
#define MaxBlocktableEntrySize
Definition: tidstore.c:86

References Assert, BITNUM, BITS_PER_BITMAPWORD, data, elog, ERROR, BlocktableEntry::full_offsets, BlocktableEntry::header, i, idx(), InvalidOffsetNumber, TidStore::local, MAX_OFFSET_IN_BITMAP, MaxBlocktableEntrySize, NUM_FULL_OFFSETS, BlocktableEntry::nwords, TidStore::shared, TidStoreIsShared, TidStore::tree, word(), WORDNUM, BlocktableEntry::words, and WORDS_PER_PAGE.

Referenced by dead_items_add(), and do_set_block_offsets().

◆ TidStoreUnlock()

void TidStoreUnlock ( TidStore ts)

Definition at line 312 of file tidstore.c.

313 {
314  if (TidStoreIsShared(ts))
315  shared_ts_unlock(ts->tree.shared);
316 }

References TidStore::shared, TidStoreIsShared, and TidStore::tree.

Referenced by check_set_block_offsets(), and do_set_block_offsets().