blob: ce57033d3fd783c3f9ef144d2b118c293c22aeb1 [file] [log] [blame]
/*-------------------------------------------------------------------------
*
* bitmap.h
* header file for on-disk bitmap index access method implementation.
*
* Copyright (c) 2006-2008, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL$
*
*-------------------------------------------------------------------------
*/
#ifndef BITMAP_H
#define BITMAP_H
#include "access/htup.h"
#include "access/itup.h"
#include "access/relscan.h"
#include "access/sdir.h"
#include "access/xlogutils.h"
#include "nodes/tidbitmap.h"
#include "storage/lock.h"
#include "miscadmin.h"
#define BM_READ BUFFER_LOCK_SHARE
#define BM_WRITE BUFFER_LOCK_EXCLUSIVE
#define BM_NOLOCK (-1)
/*
* The size in bits of a hybrid run-length(HRL) word.
* If you change this, you should change the type for
* a HRL word as well.
*/
#define BM_HRL_WORD_SIZE 64
/* the type for a HRL word */
typedef uint64 BM_HRL_WORD;
#define BM_HRL_WORD_LEFTMOST (BM_HRL_WORD_SIZE-1)
#define BITMAP_VERSION 2
#define BITMAP_MAGIC 0x4249544D
/*
* Metapage, always the first page (page 0) in the index.
*
* This page stores some meta-data information about this index.
*/
typedef struct BMMetaPageData
{
/*
* The magic and version of the bitmap index. Using the Oid type is to
* overcome the problem that the version is not stored in
* the index before GPDB 3.4.
*/
Oid bm_magic;
Oid bm_version; /* the version of the index */
/*
* The relation ids for a heap and a btree on this heap. They are
* used to speed up finding the bitmap vector for given attribute
* value(s), see the comments for LOV pages below for more
* information. We consider these as the metadata for LOV pages.
*/
Oid bm_lov_heapId; /* the relation id for the heap */
Oid bm_lov_indexId; /* the relation id for the index */
/* the block number for the last LOV pages. */
BlockNumber bm_lov_lastpage;
} BMMetaPageData;
typedef BMMetaPageData *BMMetaPage;
/*
* The meta page is always the first block of the index
*/
#define BM_METAPAGE 0
/*
* The maximum number of heap tuples in one page that is considered
* in the bitmap index. We set this number to be a multiplication
* of BM_HRL_WORD_SIZE because we can then bits for heap
* tuples in different heap pages are stored in different words.
* This makes it easier during the search.
*
* Because the tid value for AO tables can be more than MaxHeapTuplesPerPage,
* we use the maximum possible offset number here.
*/
#define BM_MAX_TUPLES_PER_PAGE \
(((((1 << (8 * sizeof(OffsetNumber))) - 1) / BM_HRL_WORD_SIZE) + 1) * \
BM_HRL_WORD_SIZE)
/*
* LOV (List Of Values) page -- pages to store a list of distinct
* values for attribute(s) to be indexed, some metadata related to
* their corresponding bitmap vectors, and the pointers to their
* bitmap vectors. For each distinct value, there is a BMLOVItemData
* associated with it. A LOV page maintains an array of BMLOVItemData
* instances, called lov items.
*
* To speed up finding the lov item for a given value, we
* create a heap to maintain all distinct values along with the
* block numbers and offset numbers for their lov items in LOV pages.
* That is, there are total "<number_of_attributes> + 2" attributes
* in this new heap. Along with this heap, we also create a new btree
* index on this heap using attribute(s) as btree keys. In this way,
* for any given value, we search this btree to find
* the block number and offset number for its corresponding lov item.
*/
/*
* The first LOV page is reserved for NULL keys
*/
#define BM_LOV_STARTPAGE 1
/*
* Items in a LOV page.
*
* Each item is corresponding to a distinct value for attribute(s)
* to be indexed. For multi-column indexes on (a_1,a_2,...,a_n), we say
* two values (l_1,l_2,...,l_n) and (k_1,k_2,...,k_n) for (a_1,a_2,...,a_n)
* are the same if and only if for all i, l_i=k_i.
*
*/
typedef struct BMLOVItemData
{
/* the first page and last page of the bitmap vector. */
BlockNumber bm_lov_head;
BlockNumber bm_lov_tail;
/*
* Additional information to be used to append new bits into
* existing bitmap vector that this distinct value is associated with.
* The following two words do not store in the regular bitmap page,
* defined below.
*/
/* the last complete word in its bitmap vector. */
BM_HRL_WORD bm_last_compword;
/*
* the last word in its bitmap vector. This word is not
* a complete word. If a new appending bit makes this word
* to be complete, this word will merge with bm_last_compword.
*/
BM_HRL_WORD bm_last_word;
/*
* the tid location for the last bit stored in bm_last_compword.
* A tid location represents the index position for a bit in a
* bitmap vector, which is conceptualized as an array
* of bits. This value -- the index position starts from 1, and
* is calculated through (block#)*BM_MAX_TUPLES_PER_PAGE + (offset#),
* where (block#) and (offset#) are from the heap tuple ctid.
* This value is used while updating a bit in the middle of
* its bitmap vector. When moving the last complete word to
* the bitmap page, this value will also be written to that page.
* Each bitmap page maintains a similar value -- the tid location
* for the last bit stored in that page. This will help us
* know the range of tid locations for bits in a bitmap page
* without decompressing all bits.
*/
uint64 bm_last_tid_location;
/*
* the tid location of the last bit whose value is 1 (a set bit).
* Each bitmap vector will be visited only when there is a new
* set bit to be appended/updated. In the appending case, a new
* tid location is presented. With this value, we can calculate
* how many bits are 0s between this new set bit and the previous
* set bit.
*/
uint64 bm_last_setbit;
/*
* Only two least-significant bits in this byte are used.
*
* If the first least-significant bit is 1, then it represents
* that bm_last_word is a fill word. If the second least-significant
* bit is 1, it represents that bm_last_compword is a fill word.
*/
uint8 lov_words_header;
} BMLOVItemData;
typedef BMLOVItemData *BMLOVItem;
#define BM_MAX_LOVITEMS_PER_PAGE \
((BLCKSZ - sizeof(PageHeaderData)) / sizeof(BMLOVItemData))
#define BM_LAST_WORD_BIT 1
#define BM_LAST_COMPWORD_BIT 2
#define BM_LASTWORD_IS_FILL(lov) \
(bool) (lov->lov_words_header & BM_LAST_WORD_BIT ? true : false)
#define BM_LAST_COMPWORD_IS_FILL(lov) \
(bool) (lov->lov_words_header & BM_LAST_COMPWORD_BIT ? true : false)
#define BM_BOTH_LOV_WORDS_FILL(lov) \
(BM_LASTWORD_IS_FILL(lov) && BM_LAST_COMPWORD_IS_FILL(lov))
/*
* Bitmap page -- pages to store bits in a bitmap vector.
*
* Each bitmap page stores two parts of information: header words and
* content words. Each bit in the header words is corresponding to
* a word in the content words. If a bit in the header words is 1,
* then its corresponding content word is a compressed word. Otherwise,
* it is a literal word.
*
* If a content word is a fill word, it means that there is a sequence
* of 0 bits or 1 bits. The most significant bit in this content word
* represents the bits in this sequence are 0s or 1s. The rest of bits
* stores the value of "the number of bits / BM_HRL_WORD_SIZE".
*/
/*
* Opaque data for a bitmap page.
*/
typedef struct BMBitmapOpaqueData
{
uint32 bm_hrl_words_used; /* the number of words used */
BlockNumber bm_bitmap_next; /* the next page for this bitmap */
/*
* the tid location for the last bit in this page.
*/
uint64 bm_last_tid_location;
} BMBitmapOpaqueData;
typedef BMBitmapOpaqueData *BMBitmapOpaque;
/*
* Approximately 4078 words per 8K page
*/
#define BM_MAX_NUM_OF_HRL_WORDS_PER_PAGE \
((BLCKSZ - \
MAXALIGN(sizeof(PageHeaderData)) - \
MAXALIGN(sizeof(BMBitmapOpaqueData)))/sizeof(BM_HRL_WORD))
/* approx 255 */
#define BM_MAX_NUM_OF_HEADER_WORDS \
(((BM_MAX_NUM_OF_HRL_WORDS_PER_PAGE-1)/BM_HRL_WORD_SIZE) + 1)
/*
* To make the last header word a complete word, we limit this number to
* the multiplication of the word size.
*/
#define BM_NUM_OF_HRL_WORDS_PER_PAGE \
(((BM_MAX_NUM_OF_HRL_WORDS_PER_PAGE - \
BM_MAX_NUM_OF_HEADER_WORDS)/BM_HRL_WORD_SIZE) * BM_HRL_WORD_SIZE)
#define BM_NUM_OF_HEADER_WORDS \
(((BM_NUM_OF_HRL_WORDS_PER_PAGE-1)/BM_HRL_WORD_SIZE) + 1)
/*
* A page of a compressed bitmap
*/
typedef struct BMBitmapData
{
BM_HRL_WORD hwords[BM_NUM_OF_HEADER_WORDS];
BM_HRL_WORD cwords[BM_NUM_OF_HRL_WORDS_PER_PAGE];
} BMBitmapData;
typedef BMBitmapData *BMBitmap;
/*
* Data structure for used to buffer index creation during bmbuild().
* Buffering provides three benefits: firstly, it makes for many fewer
* calls to the lower-level bitmap insert functions; secondly, it means that
* we reduce the amount of unnecessary compression and decompression we do;
* thirdly, in some cases pages for a given bitmap vector will be contiguous
* on disk.
*
* byte_size counts how many bytes we've consumed in the buffer.
* max_lov_block is a hint as to whether we'll find a LOV block in lov_blocks
* or not (we take advantage of the fact that LOV block numbers will be
* increasing).
* lov_blocks is a list of LOV block buffers. The structures put in
* this list are defined in bitmapinsert.c.
*/
typedef struct BMTidBuildBuf
{
uint32 byte_size; /* The size in bytes of the buffer's data */
BlockNumber max_lov_block; /* highest lov block we're seen */
List *lov_blocks; /* list of lov blocks we're buffering */
} BMTidBuildBuf;
/*
* The number of tid locations to be found at once during query processing.
*/
#define BM_BATCH_TIDS 16*1024
/*
* the maximum number of words to be retrieved during BitmapIndexScan.
*/
#define BM_MAX_WORDS BM_NUM_OF_HRL_WORDS_PER_PAGE*4
/* Some macros for manipulating a bitmap word. */
#define LITERAL_ALL_ZERO 0
#define LITERAL_ALL_ONE ((BM_HRL_WORD)(~((BM_HRL_WORD)0)))
#define FILL_MASK ~(((BM_HRL_WORD)1) << (BM_HRL_WORD_SIZE - 1))
#define BM_MAKE_FILL_WORD(bit, length) \
((((BM_HRL_WORD)bit) << (BM_HRL_WORD_SIZE-1)) | (length))
#define FILL_LENGTH(w) (((BM_HRL_WORD)(w)) & FILL_MASK)
#define MAX_FILL_LENGTH ((((BM_HRL_WORD)1)<<(BM_HRL_WORD_SIZE-1))-1)
/* get the left most bit of the word */
#define GET_FILL_BIT(w) (((BM_HRL_WORD)(w))>>BM_HRL_WORD_LEFTMOST)
/*
* Given a word number, determine the bit position it that holds in its
* header word.
*/
#define WORDNO_GET_HEADER_BIT(cw_no) \
((BM_HRL_WORD)1 << (BM_HRL_WORD_SIZE - 1 - ((cw_no) % BM_HRL_WORD_SIZE)))
/*
* To see if the content word at n is a compressed word or not we must look
* look in the header words h_words. Each bit in the header words corresponds
* to a word amongst the content words. If the bit is 1, the word is compressed
* (i.e., it is a fill word) otherwise it is uncompressed.
*
* See src/backend/access/bitmap/README for more details
*/
#define IS_FILL_WORD(h, n) \
(bool) ((((h)[(n)/BM_HRL_WORD_SIZE]) & (WORDNO_GET_HEADER_BIT(n))) > 0 ? \
true : false)
/* A simplified interface to IS_FILL_WORD */
#define CUR_WORD_IS_FILL(b) \
IS_FILL_WORD(b->hwords, b->startNo)
/*
* Calculate the number of header words we need given the number of
* content words
*/
#define BM_CALC_H_WORDS(c_words) \
(c_words == 0 ? c_words : (((c_words - 1)/BM_HRL_WORD_SIZE) + 1))
/*
* Convert an ItemPointer to and from an integer representation
*/
#define BM_IPTR_TO_INT(iptr) \
((uint64)ItemPointerGetBlockNumber(iptr) * BM_MAX_TUPLES_PER_PAGE + \
(uint64)ItemPointerGetOffsetNumber(iptr))
#define BM_INT_GET_BLOCKNO(i) \
((i - 1)/BM_MAX_TUPLES_PER_PAGE)
#define BM_INT_GET_OFFSET(i) \
(((i - 1) % BM_MAX_TUPLES_PER_PAGE) + 1)
/*
* BMTIDBuffer represents TIDs we've buffered for a given bitmap vector --
* i.e., TIDs for a distinct value in the underlying table. We take advantage
* of the fact that since we are reading the table from beginning to end
* TIDs will be ordered.
*/
typedef struct BMTIDBuffer
{
/* The last two bitmap words */
BM_HRL_WORD last_compword;
BM_HRL_WORD last_word;
bool is_last_compword_fill;
uint64 start_tid; /* starting TID for this buffer */
uint64 last_tid; /* most recent tid added */
int16 curword; /* index into content */
int16 num_cwords; /* number of allocated words in content */
/* the starting array index that contains useful content words */
int16 start_wordno;
/* the last tids, one for each actual data words */
uint64 *last_tids;
/* the header and content words */
BM_HRL_WORD hwords[BM_NUM_OF_HEADER_WORDS];
BM_HRL_WORD *cwords;
} BMTIDBuffer;
typedef struct BMBuildLovData
{
BlockNumber lov_block;
OffsetNumber lov_off;
} BMBuildLovData;
/*
* the state for index build
*/
typedef struct BMBuildState
{
TupleDesc bm_tupDesc;
Relation bm_lov_heap;
Relation bm_lov_index;
/*
* We use this hash to cache lookups of lov blocks for different keys
* When one of attribute types can not be hashed, we set this hash
* to NULL.
*/
HTAB *lovitem_hash;
/**
* when lovitem_hash is non-NULL then this will correspond to the
* size of the keys in the hash
*/
int lovitem_hashKeySize;
/*
* When the attributes to be indexed can not be hashed, we can not use
* the hash for the lov blocks. We have to search through the
* btree.
*/
ScanKey bm_lov_scanKeys;
IndexScanDesc bm_lov_scanDesc;
/*
* the buffer to store last several tid locations for each distinct
* value.
*/
BMTidBuildBuf *bm_tidLocsBuffer;
double ituples; /* the number of index tuples */
bool use_wal; /* whether or not we write WAL records */
} BMBuildState;
/**
* The key used inside BMBuildState's lovitem_hash hashtable
*
* The caller should assign attributeValueArr and isNullArr to point at the values and isnull array to be hashed
*
* When inside the hashtable, attributeValueArr and isNullArr will point to aligned memory within the key block itself
*/
typedef struct BMBuildHashKey
{
Datum *attributeValueArr;
bool *isNullArr;
} BMBuildHashKey;
/*
* Define an iteration result while scanning an BMBatchWords.
*
* This result includes the last scan position in an BMBatchWords,
* and all tids that are generated from previous scan.
*/
typedef struct BMIterateResult
{
uint64 nextTid; /* the first tid for the next iteration */
uint32 lastScanPos; /* position in the bitmap word we're looking at */
uint32 lastScanWordNo; /* offset in BWBatchWords */
uint64 nextTids[BM_BATCH_TIDS]; /* array of matching TIDs */
uint32 numOfTids; /* number of TIDs matched */
uint32 nextTidLoc; /* the next position in 'nextTids' to be read. */
} BMIterateResult;
/*
* Stores a batch of consecutive bitmap words from a bitmap vector.
*
* These bitmap words come from a bitmap vector stored in this bitmap
* index, or a bitmap vector that is generated by ANDing/ORing several
* bitmap vectors.
*
* This struct also contains information to compute the tid locations
* for the set bits in these bitmap words.
*/
typedef struct BMBatchWords
{
uint32 maxNumOfWords; /* maximum number of words in this list */
/* Number of uncompressed words that have been read already */
uint64 nwordsread;
uint64 nextread; /* next word to read */
uint64 firstTid; /* the TID we're up to */
uint32 startNo; /* position we're at in cwords */
uint32 nwords; /* the number of bitmap words */
BM_HRL_WORD *hwords; /* the header words */
BM_HRL_WORD *cwords; /* the actual bitmap words */
} BMBatchWords;
/*
* Scan opaque data for one bitmap vector.
*
* This structure stores a batch of consecutive bitmap words for a
* bitmap vector that have been read from the disk, and remembers
* the next reading position for the next batch of consecutive
* bitmap words.
*/
typedef struct BMVectorData
{
Buffer bm_lovBuffer;/* the buffer that contains the LOV item. */
OffsetNumber bm_lovOffset; /* the offset of the LOV item */
BlockNumber bm_nextBlockNo; /* the next bitmap page block */
/* indicate if the last two words in the bitmap has been read.
* These two words are stored inside a BMLovItem. If this value
* is true, it means this bitmap vector has no more words.
*/
bool bm_readLastWords;
BMBatchWords *bm_batchWords; /* actual bitmap words */
} BMVectorData;
typedef BMVectorData *BMVector;
/*
* Defines the current position of a scan.
*
* For each scan, all related bitmap vectors are read from the bitmap
* index, and ORed together into a final bitmap vector. The words
* in each bitmap vector are read in batches. This structure stores
* the following:
* (1) words for a final bitmap vector after ORing words from
* related bitmap vectors.
* (2) tid locations that satisfy the query.
* (3) One BMVectorData for each related bitmap vector.
*/
typedef struct BMScanPositionData
{
bool done; /* indicate if this scan is over */
int nvec; /* the number of related bitmap vectors */
/* the words in the final bitmap vector that satisfies the query. */
BMBatchWords *bm_batchWords;
/*
* The BMIterateResult instance that contains the final
* tid locations for tuples that satisfy the query.
*/
BMIterateResult bm_result;
BMVector posvecs; /* one or more bitmap vectors */
} BMScanPositionData;
typedef BMScanPositionData *BMScanPosition;
typedef struct BMScanOpaqueData
{
BMScanPosition bm_currPos;
bool cur_pos_valid;
/* XXX: should we pull out mark pos? */
BMScanPosition bm_markPos;
bool mark_pos_valid;
} BMScanOpaqueData;
typedef BMScanOpaqueData *BMScanOpaque;
/*
* XLOG records for bitmap index operations
*
* Some information in high 4 bits of log record xl_info field.
*/
#define XLOG_BITMAP_INSERT_NEWLOV 0x10 /* add a new LOV page */
#define XLOG_BITMAP_INSERT_LOVITEM 0x20 /* add a new entry into a LOV page */
#define XLOG_BITMAP_INSERT_META 0x30 /* update the metapage */
#define XLOG_BITMAP_INSERT_BITMAP_LASTWORDS 0x40 /* update the last 2 words
in a bitmap */
/* insert bitmap words into a bitmap page which is not the last one. */
#define XLOG_BITMAP_INSERT_WORDS 0x50
/* insert bitmap words to the last bitmap page and the lov buffer */
#define XLOG_BITMAP_INSERT_LASTWORDS 0x60
#define XLOG_BITMAP_UPDATEWORD 0x70
#define XLOG_BITMAP_UPDATEWORDS 0x80
/*
* The information about writing bitmap words to last bitmap page
* and lov page.
*/
typedef struct xl_bm_bitmapwords
{
RelFileNode bm_node;
ItemPointerData bm_persistentTid;
int64 bm_persistentSerialNum;
/* The block number for the bitmap page */
BlockNumber bm_blkno;
/* The next block number for this bitmap page */
BlockNumber bm_next_blkno;
/* The last tid location for this bitmap page */
uint64 bm_last_tid;
/*
* The block number and offset for the lov page that is associated
* with this bitmap page.
*/
BlockNumber bm_lov_blkno;
OffsetNumber bm_lov_offset;
/* The information for the lov page */
BM_HRL_WORD bm_last_compword;
BM_HRL_WORD bm_last_word;
uint8 lov_words_header;
uint64 bm_last_setbit;
/*
* Indicate if these bitmap words are stored in the last bitmap
* page and the lov buffer.
*/
bool bm_is_last;
/*
* Indicate if this is the first time to insert into a bitmap
* page.
*/
bool bm_is_first;
/*
* The words stored in the following array to be written to this
* bitmap page.
*/
uint64 bm_start_wordno;
uint64 bm_words_written;
/*
* Total number of new bitmap words. We need to log all new words
* to be able to do recovery.
*/
uint64 bm_num_cwords;
/*
* The following are arrays of last tids, content words, and header
* words. They are located one after the other. There are bm_num_cwords
* of last tids and content words, and BM_CALC_H_WORDS(bm_num_cwords)
* header words.
*/
} xl_bm_bitmapwords;
typedef struct xl_bm_updatewords
{
RelFileNode bm_node;
ItemPointerData bm_persistentTid;
int64 bm_persistentSerialNum;
BlockNumber bm_lov_blkno;
OffsetNumber bm_lov_offset;
BlockNumber bm_first_blkno;
BM_HRL_WORD bm_first_cwords[BM_NUM_OF_HRL_WORDS_PER_PAGE];
BM_HRL_WORD bm_first_hwords[BM_NUM_OF_HEADER_WORDS];
uint64 bm_first_last_tid;
uint64 bm_first_num_cwords;
BlockNumber bm_second_blkno;
BM_HRL_WORD bm_second_cwords[BM_NUM_OF_HRL_WORDS_PER_PAGE];
BM_HRL_WORD bm_second_hwords[BM_NUM_OF_HEADER_WORDS];
uint64 bm_second_last_tid;
uint64 bm_second_num_cwords;
/* Indicate if this update involves two bitmap pages */
bool bm_two_pages;
/* The previous next page number for the first page. */
BlockNumber bm_next_blkno;
/* Indicate if the second page is a new last bitmap page */
bool bm_new_lastpage;
} xl_bm_updatewords;
typedef struct xl_bm_updateword
{
RelFileNode bm_node;
ItemPointerData bm_persistentTid;
int64 bm_persistentSerialNum;
BlockNumber bm_blkno;
int bm_word_no;
BM_HRL_WORD bm_cword;
BM_HRL_WORD bm_hword;
} xl_bm_updateword;
/* The information about inserting a new lovitem into the LOV list. */
typedef struct xl_bm_lovitem
{
RelFileNode bm_node;
ItemPointerData bm_persistentTid;
int64 bm_persistentSerialNum;
BlockNumber bm_lov_blkno;
OffsetNumber bm_lov_offset;
BMLOVItemData bm_lovItem;
bool bm_is_new_lov_blkno;
} xl_bm_lovitem;
/* The information about adding a new page */
typedef struct xl_bm_newpage
{
RelFileNode bm_node;
ItemPointerData bm_persistentTid;
int64 bm_persistentSerialNum;
BlockNumber bm_new_blkno;
} xl_bm_newpage;
/*
* The information about changes on a bitmap page.
* If bm_isOpaque is true, then bm_next_blkno is set.
*/
typedef struct xl_bm_bitmappage
{
RelFileNode bm_node;
ItemPointerData bm_persistentTid;
int64 bm_persistentSerialNum;
BlockNumber bm_bitmap_blkno;
bool bm_isOpaque;
BlockNumber bm_next_blkno;
uint32 bm_last_tid_location;
uint32 bm_hrl_words_used;
uint32 bm_num_words;
/* for simplicity, we log the header words each time */
BM_HRL_WORD hwords[BM_NUM_OF_HEADER_WORDS];
/* followed by the "bm_num_words" content words. */
} xl_bm_bitmappage;
/* The information about changes to the last 2 words in a bitmap vector */
typedef struct xl_bm_bitmap_lastwords
{
RelFileNode bm_node;
ItemPointerData bm_persistentTid;
int64 bm_persistentSerialNum;
BM_HRL_WORD bm_last_compword;
BM_HRL_WORD bm_last_word;
uint8 lov_words_header;
uint64 bm_last_setbit;
uint64 bm_last_tid_location;
BlockNumber bm_lov_blkno;
OffsetNumber bm_lov_offset;
} xl_bm_bitmap_lastwords;
/* The information about the changes in the metapage. */
typedef struct xl_bm_metapage
{
RelFileNode bm_node;
ItemPointerData bm_persistentTid;
int64 bm_persistentSerialNum;
Oid bm_lov_heapId; /* the relation id for the heap */
Oid bm_lov_indexId; /* the relation id for the index */
/* the block number for the last LOV pages. */
BlockNumber bm_lov_lastpage;
} xl_bm_metapage;
/* public routines */
extern Datum bmbuild(PG_FUNCTION_ARGS);
extern Datum bminsert(PG_FUNCTION_ARGS);
extern Datum bmbeginscan(PG_FUNCTION_ARGS);
extern Datum bmgettuple(PG_FUNCTION_ARGS);
extern Datum bmgetmulti(PG_FUNCTION_ARGS);
extern Datum bmrescan(PG_FUNCTION_ARGS);
extern Datum bmendscan(PG_FUNCTION_ARGS);
extern Datum bmmarkpos(PG_FUNCTION_ARGS);
extern Datum bmrestrpos(PG_FUNCTION_ARGS);
extern Datum bmbulkdelete(PG_FUNCTION_ARGS);
extern Datum bmvacuumcleanup(PG_FUNCTION_ARGS);
extern Datum bmoptions(PG_FUNCTION_ARGS);
extern void GetBitmapIndexAuxOids(Relation index, Oid *heapId, Oid *indexId);
/* bitmappages.c */
extern Buffer _bitmap_getbuf(Relation rel, BlockNumber blkno, int access);
extern void _bitmap_wrtbuf(Buffer buf);
extern void _bitmap_relbuf(Buffer buf);
extern void _bitmap_wrtnorelbuf(Buffer buf);
extern void _bitmap_init_lovpage(Relation rel, Buffer buf);
extern void _bitmap_init_bitmappage(Relation rel, Buffer buf);
extern void _bitmap_init_buildstate(Relation index, BMBuildState* bmstate);
extern void _bitmap_cleanup_buildstate(Relation index, BMBuildState* bmstate);
extern void _bitmap_init(Relation rel, Oid comptypeOid,
Oid heapOid, Oid indexOid,
Oid heapRelfilenode, Oid indexRelfilenode,
bool use_wal);
/* bitmapinsert.c */
extern void _bitmap_buildinsert(Relation rel, ItemPointerData ht_ctid,
Datum *attdata, bool *nulls,
BMBuildState *state);
extern void _bitmap_doinsert(Relation rel, ItemPointerData ht_ctid,
Datum *attdata, bool *nulls);
extern void _bitmap_write_alltids(Relation rel, BMTidBuildBuf *tids,
bool use_wal);
extern uint64 _bitmap_write_bitmapwords(Buffer bitmapBuffer,
BMTIDBuffer* buf);
extern void _bitmap_write_new_bitmapwords(
Relation rel,
Buffer lovBuffer, OffsetNumber lovOffset,
BMTIDBuffer* buf, bool use_wal);
extern uint16 _bitmap_free_tidbuf(BMTIDBuffer* buf);
/* bitmaputil.c */
extern BMLOVItem _bitmap_formitem(uint64 currTidNumber);
extern BMMetaPage _bitmap_get_metapage_data(Relation rel, Buffer metabuf);
extern void _bitmap_init_batchwords(BMBatchWords* words,
uint32 maxNumOfWords,
MemoryContext mcxt);
extern void _bitmap_copy_batchwords(BMBatchWords *words, BMBatchWords *copyWords);
extern void _bitmap_reset_batchwords(BMBatchWords* words);
extern void _bitmap_cleanup_batchwords(BMBatchWords* words);
extern void _bitmap_cleanup_scanpos(BMVector bmScanPos,
uint32 numBitmapVectors);
extern uint64 _bitmap_findnexttid(BMBatchWords *words,
BMIterateResult *result);
extern void _bitmap_findprevtid(BMIterateResult *result);
extern void _bitmap_findnexttids(BMBatchWords *words,
BMIterateResult *result, uint32 maxTids);
extern bool _bitmap_getbitmapinpage(BMBatchWords* words,
BMIterateResult* result,
BlockNumber nextBlockNo,
PagetableEntry* entry);
#ifdef NOT_USED /* we might use this later */
extern void _bitmap_intersect(BMBatchWords **batches, uint32 numBatches,
BMBatchWords *result);
#endif
extern void _bitmap_union(BMBatchWords **batches, uint32 numBatches,
BMBatchWords *result);
extern void _bitmap_begin_iterate(BMBatchWords *words, BMIterateResult *result);
extern void _bitmap_log_newpage(Relation rel, uint8 info, Buffer buf);
extern void _bitmap_log_metapage(Relation rel, Page page);
extern void _bitmap_log_bitmap_lastwords(Relation rel, Buffer lovBuffer,
OffsetNumber lovOffset, BMLOVItem lovItem);
extern void _bitmap_log_lovitem (Relation rel, Buffer lovBuffer,
OffsetNumber offset, BMLOVItem lovItem,
Buffer metabuf, bool is_new_lov_blkno);
extern void _bitmap_log_bitmapwords(Relation rel, Buffer bitmapBuffer, Buffer lovBuffer,
OffsetNumber lovOffset, BMTIDBuffer* buf,
uint64 words_written, uint64 tidnum, BlockNumber nextBlkno,
bool isLast, bool isFirst);
extern void _bitmap_log_updatewords(Relation rel,
Buffer lovBuffer, OffsetNumber lovOffset,
Buffer firstBuffer, Buffer secondBuffer,
bool new_lastpage);
extern void _bitmap_log_updateword(Relation rel, Buffer bitmapBuffer, int word_no);
/* bitmapsearch.c */
extern bool _bitmap_first(IndexScanDesc scan, ScanDirection dir);
extern bool _bitmap_next(IndexScanDesc scan, ScanDirection dir);
extern bool _bitmap_firstbatchwords(IndexScanDesc scan, ScanDirection dir);
extern bool _bitmap_nextbatchwords(IndexScanDesc scan, ScanDirection dir);
extern void _bitmap_findbitmaps(IndexScanDesc scan, ScanDirection dir);
/* bitmapattutil.c */
extern void _bitmap_create_lov_heapandindex(Relation rel,
Oid lovComptypeOid,
Oid *lovHeapOid,
Oid *lovIndexOid,
Oid lovHeapRelfilenode,
Oid lovIndexRelfilenode);
extern void _bitmap_open_lov_heapandindex(Relation rel, BMMetaPage metapage,
Relation *lovHeapP, Relation *lovIndexP,
LOCKMODE lockMode);
extern void _bitmap_insert_lov(Relation lovHeap, Relation lovIndex,
Datum *datum, bool *nulls, bool use_wal);
extern void _bitmap_close_lov_heapandindex(Relation lovHeap,
Relation lovIndex, LOCKMODE lockMode);
extern bool _bitmap_findvalue(Relation lovHeap, Relation lovIndex,
ScanKey scanKey, IndexScanDesc scanDesc,
BlockNumber *lovBlock, bool *blockNull,
OffsetNumber *lovOffset, bool *offsetNull);
/*
* prototypes for functions in bitmapxlog.c
*/
extern void bitmap_redo(XLogRecPtr beginLoc, XLogRecPtr lsn, XLogRecord *record);
extern void bitmap_desc(StringInfo buf, XLogRecPtr beginLoc, XLogRecord *record);
extern void bitmap_xlog_startup(void);
extern void bitmap_xlog_cleanup(void);
extern bool bitmap_safe_restartpoint(void);
#endif