66#define PAGES_PER_CHUNK (BLCKSZ / 32)
70#define WORDNUM(x) ((x) / BITS_PER_BITMAPWORD)
71#define BITNUM(x) ((x) % BITS_PER_BITMAPWORD)
74#define WORDS_PER_PAGE ((TBM_MAX_TUPLES_PER_PAGE - 1) / BITS_PER_BITMAPWORD + 1)
76#define WORDS_PER_CHUNK ((PAGES_PER_CHUNK - 1) / BITS_PER_BITMAPWORD + 1)
233#define SH_USE_NONDEFAULT_ALLOCATOR
234#define SH_PREFIX pagetable
235#define SH_ELEMENT_TYPE PagetableEntry
236#define SH_KEY_TYPE BlockNumber
237#define SH_KEY blockno
238#define SH_HASH_KEY(tb, key) murmurhash32(key)
239#define SH_EQUAL(tb, a, b) a == b
240#define SH_SCOPE static inline
374 for (
int i = 0;
i < ntids;
i++)
383 elog(
ERROR,
"tuple offset out of range: %u", off);
405 wordnum = bitnum = 0;
451 if (
b->nentries == 0)
458 pagetable_iterator
i;
462 pagetable_start_iterate(
b->pagetable, &
i);
463 while ((bpage = pagetable_iterate(
b->pagetable, &
i)) != NULL)
513 apage->
words[wordnum] |= bpage->
words[wordnum];
518 if (
a->nentries >
a->maxentries)
532 if (
a->nentries == 0)
549 pagetable_iterator
i;
553 pagetable_start_iterate(
a->pagetable, &
i);
554 while ((apage = pagetable_iterate(
a->pagetable, &
i)) != NULL)
564 if (!pagetable_delete(
a->pagetable, apage->
blockno))
584 bool candelete =
true;
613 apage->
words[wordnum] = neww;
633 bool candelete =
true;
642 apage->
words[wordnum] &= bpage->
words[wordnum];
643 if (apage->
words[wordnum] != 0)
704 pagetable_iterator
i;
718 npages = nchunks = 0;
720 while ((page = pagetable_iterate(tbm->
pagetable, &
i)) != NULL)
723 tbm->
schunks[nchunks++] = page;
725 tbm->
spages[npages++] = page;
777 pagetable_iterator
i;
790 tbm->
npages *
sizeof(
int));
808 npages = nchunks = 0;
814 while ((page = pagetable_iterate(tbm->
pagetable, &
i)) != NULL)
837 ptpages->
index[0] = 0;
875 if (ptchunks != NULL)
918 if (ntuples < max_offsets)
937 int schunkbit = *schunkbitp;
941 int wordnum =
WORDNUM(schunkbit);
942 int bitnum =
BITNUM(schunkbit);
949 *schunkbitp = schunkbit;
1011 chunk_blockno < tbm->spages[iterator->
spageptr]->blockno)
1014 tbmres->
blockno = chunk_blockno;
1015 tbmres->
lossy =
true;
1035 tbmres->
lossy =
false;
1058 int *idxpages = NULL;
1059 int *idxchunks = NULL;
1061 if (iterator->
ptbase != NULL)
1063 if (iterator->
ptpages != NULL)
1106 tbmres->
blockno = chunk_blockno;
1107 tbmres->
lossy =
true;
1123 tbmres->
lossy =
false;
1186 page = pagetable_lookup(tbm->
pagetable, pageno);
1227 page = pagetable_insert(tbm->
pagetable, pageno, &found);
1233 char oldstatus = page->
status;
1236 page->
status = oldstatus;
1262 chunk_pageno = pageno - bitno;
1264 page = pagetable_lookup(tbm->
pagetable, chunk_pageno);
1266 if (page != NULL && page->
ischunk)
1269 int bitnum =
BITNUM(bitno);
1298 chunk_pageno = pageno - bitno;
1306 if (pagetable_delete(tbm->
pagetable, pageno))
1315 page = pagetable_insert(tbm->
pagetable, chunk_pageno, &found);
1320 char oldstatus = page->
status;
1323 page->
status = oldstatus;
1332 char oldstatus = page->
status;
1336 page->
status = oldstatus;
1358 pagetable_iterator
i;
1374 while ((page = pagetable_iterate(tbm->
pagetable, &
i)) != NULL)
1445 if (lpage->
blockno < rpage->blockno)
1447 else if (lpage->
blockno > rpage->blockno)
1475 iterator->
state = istate;
1499 if (tbm->
dsa == NULL)
1513 return ptbase->ptentry;
1527 if (tbm->
dsa == NULL)
1552 nbuckets = maxbytes /
1554 nbuckets =
Min(nbuckets, INT_MAX - 1);
1555 nbuckets =
Max(nbuckets, 16);
1557 return (
int) nbuckets;
Datum idx(PG_FUNCTION_ARGS)
static uint32 pg_atomic_sub_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 sub_)
static void pg_atomic_init_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
static uint32 pg_atomic_add_fetch_u32(volatile pg_atomic_uint32 *ptr, int32 add_)
#define BITS_PER_BITMAPWORD
#define InvalidBlockNumber
#define FLEXIBLE_ARRAY_MEMBER
#define MemSet(start, val, len)
void * dsa_get_address(dsa_area *area, dsa_pointer dp)
dsa_pointer dsa_allocate_extended(dsa_area *area, size_t size, int flags)
void dsa_free(dsa_area *area, dsa_pointer dp)
#define dsa_allocate0(area, size)
#define dsa_allocate(area, size)
#define InvalidDsaPointer
#define DsaPointerIsValid(x)
Assert(PointerIsAligned(start, uint64))
static int pg_cmp_u32(uint32 a, uint32 b)
if(TABLE==NULL||TABLE_index==NULL)
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
void LWLockInitialize(LWLock *lock, int tranche_id)
void * MemoryContextAlloc(MemoryContext context, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void * MemoryContextAllocExtended(MemoryContext context, Size size, int flags)
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
#define qsort(a, b, c, d)
pg_atomic_uint32 refcount
PagetableEntry ptentry[FLEXIBLE_ARRAY_MEMBER]
pg_atomic_uint32 refcount
int index[FLEXIBLE_ARRAY_MEMBER]
bitmapword words[Max(WORDS_PER_PAGE, WORDS_PER_CHUNK)]
TBMSharedIterator * shared_iterator
union TBMIterator::@111 i
TBMPrivateIterator * private_iterator
TBMSharedIteratorState * state
PTIterationArray * ptchunks
PTIterationArray * ptpages
TBMIteratingState iterating
dsa_pointer dsapagetableold
struct pagetable_hash * pagetable
PagetableEntry ** schunks
void tbm_free(TIDBitmap *tbm)
struct PTIterationArray PTIterationArray
bool tbm_iterate(TBMIterator *iterator, TBMIterateResult *tbmres)
bool tbm_shared_iterate(TBMSharedIterator *iterator, TBMIterateResult *tbmres)
static void tbm_lossify(TIDBitmap *tbm)
bool tbm_is_empty(const TIDBitmap *tbm)
void tbm_end_iterate(TBMIterator *iterator)
void tbm_end_shared_iterate(TBMSharedIterator *iterator)
static bool tbm_page_is_lossy(const TIDBitmap *tbm, BlockNumber pageno)
static void * pagetable_allocate(pagetable_hash *pagetable, Size size)
dsa_pointer tbm_prepare_shared_iterate(TIDBitmap *tbm)
void tbm_intersect(TIDBitmap *a, const TIDBitmap *b)
void tbm_free_shared_area(dsa_area *dsa, dsa_pointer dp)
static void tbm_mark_page_lossy(TIDBitmap *tbm, BlockNumber pageno)
static void tbm_union_page(TIDBitmap *a, const PagetableEntry *bpage)
static const PagetableEntry * tbm_find_pageentry(const TIDBitmap *tbm, BlockNumber pageno)
bool tbm_private_iterate(TBMPrivateIterator *iterator, TBMIterateResult *tbmres)
void tbm_add_page(TIDBitmap *tbm, BlockNumber pageno)
static void tbm_advance_schunkbit(PagetableEntry *chunk, int *schunkbitp)
TBMSharedIterator * tbm_attach_shared_iterate(dsa_area *dsa, dsa_pointer dp)
TBMIterator tbm_begin_iterate(TIDBitmap *tbm, dsa_area *dsa, dsa_pointer dsp)
static int tbm_shared_comparator(const void *left, const void *right, void *arg)
static int tbm_comparator(const void *left, const void *right)
static void tbm_create_pagetable(TIDBitmap *tbm)
int tbm_extract_page_tuple(TBMIterateResult *iteritem, OffsetNumber *offsets, uint32 max_offsets)
void tbm_union(TIDBitmap *a, const TIDBitmap *b)
void tbm_end_private_iterate(TBMPrivateIterator *iterator)
TIDBitmap * tbm_create(Size maxbytes, dsa_area *dsa)
struct PagetableEntry PagetableEntry
TBMPrivateIterator * tbm_begin_private_iterate(TIDBitmap *tbm)
struct PTEntryArray PTEntryArray
void tbm_add_tuples(TIDBitmap *tbm, const ItemPointerData *tids, int ntids, bool recheck)
int tbm_calculate_entries(Size maxbytes)
static bool tbm_intersect_page(TIDBitmap *a, PagetableEntry *apage, const TIDBitmap *b)
struct TBMSharedIteratorState TBMSharedIteratorState
static void pagetable_free(pagetable_hash *pagetable, void *pointer)
static PagetableEntry * tbm_get_pageentry(TIDBitmap *tbm, BlockNumber pageno)
struct TBMIterator TBMIterator
#define TBM_MAX_TUPLES_PER_PAGE
static bool tbm_exhausted(TBMIterator *iterator)