PostgreSQL Source Code  git master
tidstore.c File Reference
#include "postgres.h"
#include "access/tidstore.h"
#include "miscadmin.h"
#include "nodes/bitmapset.h"
#include "storage/lwlock.h"
#include "utils/dsa.h"
#include "lib/radixtree.h"
Include dependency graph for tidstore.c:

Go to the source code of this file.

Data Structures

struct  BlocktableEntry
 
struct  TidStore
 
struct  TidStoreIter
 

Macros

#define WORDNUM(x)   ((x) / BITS_PER_BITMAPWORD)
 
#define BITNUM(x)   ((x) % BITS_PER_BITMAPWORD)
 
#define WORDS_PER_PAGE(n)   ((n) / BITS_PER_BITMAPWORD + 1)
 
#define NUM_FULL_OFFSETS   ((sizeof(uintptr_t) - sizeof(uint8) - sizeof(int8)) / sizeof(OffsetNumber))
 
#define MAX_OFFSET_IN_BITMAP   Min(BITS_PER_BITMAPWORD * PG_INT8_MAX - 1, MaxOffsetNumber)
 
#define MaxBlocktableEntrySize
 
#define RT_PREFIX   local_ts
 
#define RT_SCOPE   static
 
#define RT_DECLARE
 
#define RT_DEFINE
 
#define RT_VALUE_TYPE   BlocktableEntry
 
#define RT_VARLEN_VALUE_SIZE(page)
 
#define RT_RUNTIME_EMBEDDABLE_VALUE
 
#define RT_PREFIX   shared_ts
 
#define RT_SHMEM
 
#define RT_SCOPE   static
 
#define RT_DECLARE
 
#define RT_DEFINE
 
#define RT_VALUE_TYPE   BlocktableEntry
 
#define RT_VARLEN_VALUE_SIZE(page)
 
#define RT_RUNTIME_EMBEDDABLE_VALUE
 
#define TidStoreIsShared(ts)   ((ts)->area != NULL)
 

Typedefs

typedef struct BlocktableEntry BlocktableEntry
 

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_areaTidStoreGetDSA (TidStore *ts)
 
dsa_pointer TidStoreGetHandle (TidStore *ts)
 
int TidStoreGetBlockOffsets (TidStoreIterResult *result, OffsetNumber *offsets, int max_offsets)
 

Macro Definition Documentation

◆ BITNUM

#define BITNUM (   x)    ((x) % BITS_PER_BITMAPWORD)

Definition at line 32 of file tidstore.c.

◆ MAX_OFFSET_IN_BITMAP

#define MAX_OFFSET_IN_BITMAP   Min(BITS_PER_BITMAPWORD * PG_INT8_MAX - 1, MaxOffsetNumber)

Definition at line 84 of file tidstore.c.

◆ MaxBlocktableEntrySize

#define MaxBlocktableEntrySize
Value:
offsetof(BlocktableEntry, words) + \
uint32 bitmapword
Definition: bitmapset.h:44
#define WORDS_PER_PAGE(n)
Definition: tidstore.c:35
#define MAX_OFFSET_IN_BITMAP
Definition: tidstore.c:84

Definition at line 86 of file tidstore.c.

◆ NUM_FULL_OFFSETS

#define NUM_FULL_OFFSETS   ((sizeof(uintptr_t) - sizeof(uint8) - sizeof(int8)) / sizeof(OffsetNumber))

Definition at line 38 of file tidstore.c.

◆ RT_DECLARE [1/2]

#define RT_DECLARE

Definition at line 104 of file tidstore.c.

◆ RT_DECLARE [2/2]

#define RT_DECLARE

Definition at line 104 of file tidstore.c.

◆ RT_DEFINE [1/2]

#define RT_DEFINE

Definition at line 105 of file tidstore.c.

◆ RT_DEFINE [2/2]

#define RT_DEFINE

Definition at line 105 of file tidstore.c.

◆ RT_PREFIX [1/2]

#define RT_PREFIX   local_ts

Definition at line 101 of file tidstore.c.

◆ RT_PREFIX [2/2]

#define RT_PREFIX   shared_ts

Definition at line 101 of file tidstore.c.

◆ RT_RUNTIME_EMBEDDABLE_VALUE [1/2]

#define RT_RUNTIME_EMBEDDABLE_VALUE

Definition at line 110 of file tidstore.c.

◆ RT_RUNTIME_EMBEDDABLE_VALUE [2/2]

#define RT_RUNTIME_EMBEDDABLE_VALUE

Definition at line 110 of file tidstore.c.

◆ RT_SCOPE [1/2]

#define RT_SCOPE   static

Definition at line 103 of file tidstore.c.

◆ RT_SCOPE [2/2]

#define RT_SCOPE   static

Definition at line 103 of file tidstore.c.

◆ RT_SHMEM

#define RT_SHMEM

Definition at line 102 of file tidstore.c.

◆ RT_VALUE_TYPE [1/2]

#define RT_VALUE_TYPE   BlocktableEntry

Definition at line 106 of file tidstore.c.

◆ RT_VALUE_TYPE [2/2]

#define RT_VALUE_TYPE   BlocktableEntry

Definition at line 106 of file tidstore.c.

◆ RT_VARLEN_VALUE_SIZE [1/2]

#define RT_VARLEN_VALUE_SIZE (   page)
Value:
(offsetof(BlocktableEntry, words) + \
sizeof(bitmapword) * (page)->header.nwords)

Definition at line 107 of file tidstore.c.

◆ RT_VARLEN_VALUE_SIZE [2/2]

#define RT_VARLEN_VALUE_SIZE (   page)
Value:
(offsetof(BlocktableEntry, words) + \
sizeof(bitmapword) * (page)->header.nwords)

Definition at line 107 of file tidstore.c.

◆ TidStoreIsShared

#define TidStoreIsShared (   ts)    ((ts)->area != NULL)

Definition at line 132 of file tidstore.c.

◆ WORDNUM

#define WORDNUM (   x)    ((x) / BITS_PER_BITMAPWORD)

Definition at line 31 of file tidstore.c.

◆ WORDS_PER_PAGE

#define WORDS_PER_PAGE (   n)    ((n) / BITS_PER_BITMAPWORD + 1)

Definition at line 35 of file tidstore.c.

Typedef Documentation

◆ BlocktableEntry

Function Documentation

◆ TidStoreAttach()

TidStore* TidStoreAttach ( dsa_handle  area_handle,
dsa_pointer  handle 
)

Definition at line 252 of file tidstore.c.

253 {
254  TidStore *ts;
255  dsa_area *area;
256 
257  Assert(area_handle != DSA_HANDLE_INVALID);
258  Assert(DsaPointerIsValid(handle));
259 
260  /* create per-backend state */
261  ts = palloc0(sizeof(TidStore));
262 
263  area = dsa_attach(area_handle);
264 
265  /* Find the shared the shared radix tree */
266  ts->tree.shared = shared_ts_attach(area, handle);
267  ts->area = area;
268 
269  return ts;
270 }
#define Assert(condition)
Definition: c.h:812
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:1347
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 479 of file tidstore.c.

480 {
481  TidStoreIter *iter;
482 
483  iter = palloc0(sizeof(TidStoreIter));
484  iter->ts = ts;
485 
486  if (TidStoreIsShared(ts))
487  iter->tree_iter.shared = shared_ts_begin_iterate(ts->tree.shared);
488  else
489  iter->tree_iter.local = local_ts_begin_iterate(ts->tree.local);
490 
491  return iter;
492 }
shared_ts_iter * shared
Definition: tidstore.c:142
local_ts_iter * local
Definition: tidstore.c:143
TidStore * ts
Definition: tidstore.c:137
union TidStoreIter::@14 tree_iter
local_ts_radix_tree * local
Definition: tidstore.c:125
#define TidStoreIsShared(ts)
Definition: tidstore.c:132

References TidStore::local, TidStoreIter::local, 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 162 of file tidstore.c.

163 {
164  TidStore *ts;
165  size_t initBlockSize = ALLOCSET_DEFAULT_INITSIZE;
166  size_t minContextSize = ALLOCSET_DEFAULT_MINSIZE;
167  size_t maxBlockSize = ALLOCSET_DEFAULT_MAXSIZE;
168 
169  ts = palloc0(sizeof(TidStore));
171 
172  /* choose the maxBlockSize to be no larger than 1/16 of max_bytes */
173  while (16 * maxBlockSize > max_bytes)
174  maxBlockSize >>= 1;
175 
176  if (maxBlockSize < ALLOCSET_DEFAULT_INITSIZE)
177  maxBlockSize = ALLOCSET_DEFAULT_INITSIZE;
178 
179  /* Create a memory context for the TID storage */
180  if (insert_only)
181  {
183  "TID storage",
184  minContextSize,
185  initBlockSize,
186  maxBlockSize);
187  }
188  else
189  {
191  "TID storage",
192  minContextSize,
193  initBlockSize,
194  maxBlockSize);
195  }
196 
197  ts->tree.local = local_ts_create(ts->rt_context);
198 
199  return ts;
200 }
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 210 of file tidstore.c.

211 {
212  TidStore *ts;
213  dsa_area *area;
214  size_t dsa_init_size = DSA_DEFAULT_INIT_SEGMENT_SIZE;
215  size_t dsa_max_size = DSA_MAX_SEGMENT_SIZE;
216 
217  ts = palloc0(sizeof(TidStore));
219 
221  "TID storage meta data",
223 
224  /*
225  * Choose the initial and maximum DSA segment sizes to be no longer than
226  * 1/8 of max_bytes.
227  */
228  while (8 * dsa_max_size > max_bytes)
229  dsa_max_size >>= 1;
230 
231  if (dsa_max_size < DSA_MIN_SEGMENT_SIZE)
232  dsa_max_size = DSA_MIN_SEGMENT_SIZE;
233 
234  if (dsa_init_size > dsa_max_size)
235  dsa_init_size = dsa_max_size;
236 
237  area = dsa_create_ext(tranche_id, dsa_init_size, dsa_max_size);
238  ts->tree.shared = shared_ts_create(ts->rt_context, area,
239  tranche_id);
240  ts->area = area;
241 
242  return ts;
243 }
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 325 of file tidstore.c.

326 {
327  /* Destroy underlying radix tree */
328  if (TidStoreIsShared(ts))
329  {
330  shared_ts_free(ts->tree.shared);
331 
332  dsa_detach(ts->area);
333  }
334  else
335  local_ts_free(ts->tree.local);
336 
338 
339  pfree(ts);
340 }
void dsa_detach(dsa_area *area)
Definition: dsa.c:1952
void pfree(void *pointer)
Definition: mcxt.c:1521
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 277 of file tidstore.c.

278 {
280 
281  shared_ts_detach(ts->tree.shared);
282  dsa_detach(ts->area);
283 
284  pfree(ts);
285 }

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 526 of file tidstore.c.

527 {
528  if (TidStoreIsShared(iter->ts))
529  shared_ts_end_iterate(iter->tree_iter.shared);
530  else
531  local_ts_end_iterate(iter->tree_iter.local);
532 
533  pfree(iter);
534 }

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

Referenced by check_set_block_offsets(), and lazy_vacuum_heap_rel().

◆ TidStoreGetBlockOffsets()

int TidStoreGetBlockOffsets ( TidStoreIterResult result,
OffsetNumber offsets,
int  max_offsets 
)

Definition at line 574 of file tidstore.c.

577 {
578  BlocktableEntry *page = result->internal_page;
579  int num_offsets = 0;
580  int wordnum;
581 
582  if (page->header.nwords == 0)
583  {
584  /* we have offsets in the header */
585  for (int i = 0; i < NUM_FULL_OFFSETS; i++)
586  {
588  {
589  if (num_offsets < max_offsets)
590  offsets[num_offsets] = page->header.full_offsets[i];
591  num_offsets++;
592  }
593  }
594  }
595  else
596  {
597  for (wordnum = 0; wordnum < page->header.nwords; wordnum++)
598  {
599  bitmapword w = page->words[wordnum];
600  int off = wordnum * BITS_PER_BITMAPWORD;
601 
602  while (w != 0)
603  {
604  if (w & 1)
605  {
606  if (num_offsets < max_offsets)
607  offsets[num_offsets] = (OffsetNumber) off;
608  num_offsets++;
609  }
610  off++;
611  w >>= 1;
612  }
613  }
614  }
615 
616  return num_offsets;
617 }
#define BITS_PER_BITMAPWORD
Definition: bitmapset.h:43
int i
Definition: isn.c:72
#define InvalidOffsetNumber
Definition: off.h:26
uint16 OffsetNumber
Definition: off.h:24
bitmapword words[FLEXIBLE_ARRAY_MEMBER]
Definition: tidstore.c:76
struct BlocktableEntry::@12 header
OffsetNumber full_offsets[NUM_FULL_OFFSETS]
Definition: tidstore.c:63
void * internal_page
Definition: tidstore.h:30
#define NUM_FULL_OFFSETS
Definition: tidstore.c:38

References BITS_PER_BITMAPWORD, BlocktableEntry::full_offsets, BlocktableEntry::header, i, TidStoreIterResult::internal_page, InvalidOffsetNumber, NUM_FULL_OFFSETS, BlocktableEntry::nwords, and BlocktableEntry::words.

Referenced by check_set_block_offsets(), and lazy_vacuum_heap_rel().

◆ TidStoreGetDSA()

dsa_area* TidStoreGetDSA ( TidStore ts)

Definition at line 552 of file tidstore.c.

553 {
555 
556  return ts->area;
557 }

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 560 of file tidstore.c.

561 {
563 
564  return (dsa_pointer) shared_ts_get_handle(ts->tree.shared);
565 }
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 429 of file tidstore.c.

430 {
431  int wordnum;
432  int bitnum;
433  BlocktableEntry *page;
436 
437  if (TidStoreIsShared(ts))
438  page = shared_ts_find(ts->tree.shared, blk);
439  else
440  page = local_ts_find(ts->tree.local, blk);
441 
442  /* no entry for the blk */
443  if (page == NULL)
444  return false;
445 
446  if (page->header.nwords == 0)
447  {
448  /* we have offsets in the header */
449  for (int i = 0; i < NUM_FULL_OFFSETS; i++)
450  {
451  if (page->header.full_offsets[i] == off)
452  return true;
453  }
454  return false;
455  }
456  else
457  {
458  wordnum = WORDNUM(off);
459  bitnum = BITNUM(off);
460 
461  /* no bitmap for the off */
462  if (wordnum >= page->header.nwords)
463  return false;
464 
465  return (page->words[wordnum] & ((bitmapword) 1 << bitnum)) != 0;
466  }
467 }
uint32 BlockNumber
Definition: block.h:31
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
Definition: itemptr.h:124
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
Definition: itemptr.h:103
#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 501 of file tidstore.c.

502 {
503  uint64 key;
504  BlocktableEntry *page;
505 
506  if (TidStoreIsShared(iter->ts))
507  page = shared_ts_iterate_next(iter->tree_iter.shared, &key);
508  else
509  page = local_ts_iterate_next(iter->tree_iter.local, &key);
510 
511  if (page == NULL)
512  return NULL;
513 
514  iter->output.blkno = key;
515  iter->output.internal_page = page;
516 
517  return &(iter->output);
518 }
uint64_t uint64
Definition: c.h:486
BlockNumber blkno
Definition: tidstore.h:29
TidStoreIterResult output
Definition: tidstore.c:147

References TidStoreIterResult::blkno, TidStoreIterResult::internal_page, sort-test::key, TidStoreIter::local, TidStoreIter::output, TidStoreIter::shared, 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 295 of file tidstore.c.

296 {
297  if (TidStoreIsShared(ts))
298  shared_ts_lock_exclusive(ts->tree.shared);
299 }

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

Referenced by do_set_block_offsets().

◆ TidStoreLockShare()

void TidStoreLockShare ( TidStore ts)

Definition at line 302 of file tidstore.c.

303 {
304  if (TidStoreIsShared(ts))
305  shared_ts_lock_share(ts->tree.shared);
306 }

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

Referenced by check_set_block_offsets().

◆ TidStoreMemoryUsage()

size_t TidStoreMemoryUsage ( TidStore ts)

Definition at line 540 of file tidstore.c.

541 {
542  if (TidStoreIsShared(ts))
543  return shared_ts_memory_usage(ts->tree.shared);
544  else
545  return local_ts_memory_usage(ts->tree.local);
546 }

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 353 of file tidstore.c.

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

310 {
311  if (TidStoreIsShared(ts))
312  shared_ts_unlock(ts->tree.shared);
313 }

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

Referenced by check_set_block_offsets(), and do_set_block_offsets().