LCOV - differential code coverage report
Current view: top level - src/include/access - gist.h (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 54.5 % 11 6 5 6
Current Date: 2024-04-14 14:21:10 Functions: 50.0 % 2 1 1 1
Baseline: 16@8cea358b128 Branches: 16.7 % 6 1 5 1
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 54.5 % 11 6 5 6
Function coverage date bins:
(240..) days: 50.0 % 2 1 1 1
Branch coverage date bins:
(240..) days: 16.7 % 6 1 5 1

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * gist.h
                                  4                 :                :  *    The public API for GiST indexes. This API is exposed to
                                  5                 :                :  *    individuals implementing GiST indexes, so backward-incompatible
                                  6                 :                :  *    changes should be made with care.
                                  7                 :                :  *
                                  8                 :                :  *
                                  9                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                 10                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 11                 :                :  *
                                 12                 :                :  * src/include/access/gist.h
                                 13                 :                :  *
                                 14                 :                :  *-------------------------------------------------------------------------
                                 15                 :                :  */
                                 16                 :                : #ifndef GIST_H
                                 17                 :                : #define GIST_H
                                 18                 :                : 
                                 19                 :                : #include "access/itup.h"
                                 20                 :                : #include "access/stratnum.h"
                                 21                 :                : #include "access/transam.h"
                                 22                 :                : #include "access/xlog.h"
                                 23                 :                : #include "access/xlogdefs.h"
                                 24                 :                : #include "storage/block.h"
                                 25                 :                : #include "storage/bufpage.h"
                                 26                 :                : #include "utils/relcache.h"
                                 27                 :                : 
                                 28                 :                : /*
                                 29                 :                :  * amproc indexes for GiST indexes.
                                 30                 :                :  */
                                 31                 :                : #define GIST_CONSISTENT_PROC            1
                                 32                 :                : #define GIST_UNION_PROC                 2
                                 33                 :                : #define GIST_COMPRESS_PROC              3
                                 34                 :                : #define GIST_DECOMPRESS_PROC            4
                                 35                 :                : #define GIST_PENALTY_PROC               5
                                 36                 :                : #define GIST_PICKSPLIT_PROC             6
                                 37                 :                : #define GIST_EQUAL_PROC                 7
                                 38                 :                : #define GIST_DISTANCE_PROC              8
                                 39                 :                : #define GIST_FETCH_PROC                 9
                                 40                 :                : #define GIST_OPTIONS_PROC               10
                                 41                 :                : #define GIST_SORTSUPPORT_PROC           11
                                 42                 :                : #define GIST_STRATNUM_PROC              12
                                 43                 :                : #define GISTNProcs                  12
                                 44                 :                : 
                                 45                 :                : /*
                                 46                 :                :  * Page opaque data in a GiST index page.
                                 47                 :                :  */
                                 48                 :                : #define F_LEAF              (1 << 0)  /* leaf page */
                                 49                 :                : #define F_DELETED           (1 << 1)  /* the page has been deleted */
                                 50                 :                : #define F_TUPLES_DELETED    (1 << 2)  /* some tuples on the page were
                                 51                 :                :                                          * deleted */
                                 52                 :                : #define F_FOLLOW_RIGHT      (1 << 3)  /* page to the right has no downlink */
                                 53                 :                : #define F_HAS_GARBAGE       (1 << 4)  /* some tuples on the page are dead,
                                 54                 :                :                                          * but not deleted yet */
                                 55                 :                : 
                                 56                 :                : /*
                                 57                 :                :  * NSN (node sequence number) is a special-purpose LSN which is stored on each
                                 58                 :                :  * index page in GISTPageOpaqueData and updated only during page splits.  By
                                 59                 :                :  * recording the parent's LSN in GISTSearchItem.parentlsn, it is possible to
                                 60                 :                :  * detect concurrent child page splits by checking if parentlsn < child's NSN,
                                 61                 :                :  * and handle them properly.  The child page's LSN is insufficient for this
                                 62                 :                :  * purpose since it is updated for every page change.
                                 63                 :                :  */
                                 64                 :                : typedef XLogRecPtr GistNSN;
                                 65                 :                : 
                                 66                 :                : /*
                                 67                 :                :  * A fake LSN / NSN value used during index builds. Must be smaller than any
                                 68                 :                :  * real or fake (unlogged) LSN generated after the index build completes so
                                 69                 :                :  * that all splits are considered complete.
                                 70                 :                :  */
                                 71                 :                : #define GistBuildLSN    ((XLogRecPtr) 1)
                                 72                 :                : 
                                 73                 :                : /*
                                 74                 :                :  * For on-disk compatibility with pre-9.3 servers, NSN is stored as two
                                 75                 :                :  * 32-bit fields on disk, same as LSNs.
                                 76                 :                :  */
                                 77                 :                : typedef PageXLogRecPtr PageGistNSN;
                                 78                 :                : 
                                 79                 :                : typedef struct GISTPageOpaqueData
                                 80                 :                : {
                                 81                 :                :     PageGistNSN nsn;            /* this value must change on page split */
                                 82                 :                :     BlockNumber rightlink;      /* next page if any */
                                 83                 :                :     uint16      flags;          /* see bit definitions above */
                                 84                 :                :     uint16      gist_page_id;   /* for identification of GiST indexes */
                                 85                 :                : } GISTPageOpaqueData;
                                 86                 :                : 
                                 87                 :                : typedef GISTPageOpaqueData *GISTPageOpaque;
                                 88                 :                : 
                                 89                 :                : /*
                                 90                 :                :  * Maximum possible sizes for GiST index tuple and index key.  Calculation is
                                 91                 :                :  * based on assumption that GiST page should fit at least 4 tuples.  In theory,
                                 92                 :                :  * GiST index can be functional when page can fit 3 tuples.  But that seems
                                 93                 :                :  * rather inefficient, so we use a bit conservative estimate.
                                 94                 :                :  *
                                 95                 :                :  * The maximum size of index key is true for unicolumn index.  Therefore, this
                                 96                 :                :  * estimation should be used to figure out which maximum size of GiST index key
                                 97                 :                :  * makes sense at all.  For multicolumn indexes, user might be able to tune
                                 98                 :                :  * key size using opclass parameters.
                                 99                 :                :  */
                                100                 :                : #define GISTMaxIndexTupleSize   \
                                101                 :                :     MAXALIGN_DOWN((BLCKSZ - SizeOfPageHeaderData - sizeof(GISTPageOpaqueData)) / \
                                102                 :                :                   4 - sizeof(ItemIdData))
                                103                 :                : 
                                104                 :                : #define GISTMaxIndexKeySize \
                                105                 :                :     (GISTMaxIndexTupleSize - MAXALIGN(sizeof(IndexTupleData)))
                                106                 :                : 
                                107                 :                : /*
                                108                 :                :  * The page ID is for the convenience of pg_filedump and similar utilities,
                                109                 :                :  * which otherwise would have a hard time telling pages of different index
                                110                 :                :  * types apart.  It should be the last 2 bytes on the page.  This is more or
                                111                 :                :  * less "free" due to alignment considerations.
                                112                 :                :  */
                                113                 :                : #define GIST_PAGE_ID        0xFF81
                                114                 :                : 
                                115                 :                : /*
                                116                 :                :  * This is the Split Vector to be returned by the PickSplit method.
                                117                 :                :  * PickSplit should fill the indexes of tuples to go to the left side into
                                118                 :                :  * spl_left[], and those to go to the right into spl_right[] (note the method
                                119                 :                :  * is responsible for palloc'ing both of these arrays!).  The tuple counts
                                120                 :                :  * go into spl_nleft/spl_nright, and spl_ldatum/spl_rdatum must be set to
                                121                 :                :  * the union keys for each side.
                                122                 :                :  *
                                123                 :                :  * If spl_ldatum_exists and spl_rdatum_exists are true, then we are performing
                                124                 :                :  * a "secondary split" using a non-first index column.  In this case some
                                125                 :                :  * decisions have already been made about a page split, and the set of tuples
                                126                 :                :  * being passed to PickSplit is just the tuples about which we are undecided.
                                127                 :                :  * spl_ldatum/spl_rdatum then contain the union keys for the tuples already
                                128                 :                :  * chosen to go left or right.  Ideally the PickSplit method should take those
                                129                 :                :  * keys into account while deciding what to do with the remaining tuples, ie
                                130                 :                :  * it should try to "build out" from those unions so as to minimally expand
                                131                 :                :  * them.  If it does so, it should union the given tuples' keys into the
                                132                 :                :  * existing spl_ldatum/spl_rdatum values rather than just setting those values
                                133                 :                :  * from scratch, and then set spl_ldatum_exists/spl_rdatum_exists to false to
                                134                 :                :  * show it has done this.
                                135                 :                :  *
                                136                 :                :  * If the PickSplit method fails to clear spl_ldatum_exists/spl_rdatum_exists,
                                137                 :                :  * the core GiST code will make its own decision about how to merge the
                                138                 :                :  * secondary-split results with the previously-chosen tuples, and will then
                                139                 :                :  * recompute the union keys from scratch.  This is a workable though often not
                                140                 :                :  * optimal approach.
                                141                 :                :  */
                                142                 :                : typedef struct GIST_SPLITVEC
                                143                 :                : {
                                144                 :                :     OffsetNumber *spl_left;     /* array of entries that go left */
                                145                 :                :     int         spl_nleft;      /* size of this array */
                                146                 :                :     Datum       spl_ldatum;     /* Union of keys in spl_left */
                                147                 :                :     bool        spl_ldatum_exists;  /* true, if spl_ldatum already exists. */
                                148                 :                : 
                                149                 :                :     OffsetNumber *spl_right;    /* array of entries that go right */
                                150                 :                :     int         spl_nright;     /* size of the array */
                                151                 :                :     Datum       spl_rdatum;     /* Union of keys in spl_right */
                                152                 :                :     bool        spl_rdatum_exists;  /* true, if spl_rdatum already exists. */
                                153                 :                : } GIST_SPLITVEC;
                                154                 :                : 
                                155                 :                : /*
                                156                 :                :  * An entry on a GiST node.  Contains the key, as well as its own
                                157                 :                :  * location (rel,page,offset) which can supply the matching pointer.
                                158                 :                :  * leafkey is a flag to tell us if the entry is in a leaf node.
                                159                 :                :  */
                                160                 :                : typedef struct GISTENTRY
                                161                 :                : {
                                162                 :                :     Datum       key;
                                163                 :                :     Relation    rel;
                                164                 :                :     Page        page;
                                165                 :                :     OffsetNumber offset;
                                166                 :                :     bool        leafkey;
                                167                 :                : } GISTENTRY;
                                168                 :                : 
                                169                 :                : #define GistPageGetOpaque(page) ( (GISTPageOpaque) PageGetSpecialPointer(page) )
                                170                 :                : 
                                171                 :                : #define GistPageIsLeaf(page)    ( GistPageGetOpaque(page)->flags & F_LEAF)
                                172                 :                : #define GIST_LEAF(entry) (GistPageIsLeaf((entry)->page))
                                173                 :                : 
                                174                 :                : #define GistPageIsDeleted(page) ( GistPageGetOpaque(page)->flags & F_DELETED)
                                175                 :                : 
                                176                 :                : #define GistTuplesDeleted(page) ( GistPageGetOpaque(page)->flags & F_TUPLES_DELETED)
                                177                 :                : #define GistMarkTuplesDeleted(page) ( GistPageGetOpaque(page)->flags |= F_TUPLES_DELETED)
                                178                 :                : #define GistClearTuplesDeleted(page)    ( GistPageGetOpaque(page)->flags &= ~F_TUPLES_DELETED)
                                179                 :                : 
                                180                 :                : #define GistPageHasGarbage(page) ( GistPageGetOpaque(page)->flags & F_HAS_GARBAGE)
                                181                 :                : #define GistMarkPageHasGarbage(page) ( GistPageGetOpaque(page)->flags |= F_HAS_GARBAGE)
                                182                 :                : #define GistClearPageHasGarbage(page)   ( GistPageGetOpaque(page)->flags &= ~F_HAS_GARBAGE)
                                183                 :                : 
                                184                 :                : #define GistFollowRight(page) ( GistPageGetOpaque(page)->flags & F_FOLLOW_RIGHT)
                                185                 :                : #define GistMarkFollowRight(page) ( GistPageGetOpaque(page)->flags |= F_FOLLOW_RIGHT)
                                186                 :                : #define GistClearFollowRight(page)  ( GistPageGetOpaque(page)->flags &= ~F_FOLLOW_RIGHT)
                                187                 :                : 
                                188                 :                : #define GistPageGetNSN(page) ( PageXLogRecPtrGet(GistPageGetOpaque(page)->nsn))
                                189                 :                : #define GistPageSetNSN(page, val) ( PageXLogRecPtrSet(GistPageGetOpaque(page)->nsn, val))
                                190                 :                : 
                                191                 :                : 
                                192                 :                : /*
                                193                 :                :  * On a deleted page, we store this struct. A deleted page doesn't contain any
                                194                 :                :  * tuples, so we don't use the normal page layout with line pointers. Instead,
                                195                 :                :  * this struct is stored right after the standard page header. pd_lower points
                                196                 :                :  * to the end of this struct. If we add fields to this struct in the future, we
                                197                 :                :  * can distinguish the old and new formats by pd_lower.
                                198                 :                :  */
                                199                 :                : typedef struct GISTDeletedPageContents
                                200                 :                : {
                                201                 :                :     /* last xid which could see the page in a scan */
                                202                 :                :     FullTransactionId deleteXid;
                                203                 :                : } GISTDeletedPageContents;
                                204                 :                : 
                                205                 :                : static inline void
 1726 heikki.linnakangas@i      206                 :CBC         324 : GistPageSetDeleted(Page page, FullTransactionId deletexid)
                                207                 :                : {
                                208         [ -  + ]:            324 :     Assert(PageIsEmpty(page));
                                209                 :                : 
                                210                 :            324 :     GistPageGetOpaque(page)->flags |= F_DELETED;
                                211                 :            324 :     ((PageHeader) page)->pd_lower = MAXALIGN(SizeOfPageHeaderData) + sizeof(GISTDeletedPageContents);
                                212                 :                : 
                                213                 :            324 :     ((GISTDeletedPageContents *) PageGetContents(page))->deleteXid = deletexid;
                                214                 :            324 : }
                                215                 :                : 
                                216                 :                : static inline FullTransactionId
 1726 heikki.linnakangas@i      217                 :UBC           0 : GistPageGetDeleteXid(Page page)
                                218                 :                : {
                                219         [ #  # ]:              0 :     Assert(GistPageIsDeleted(page));
                                220                 :                : 
                                221                 :                :     /* Is the deleteXid field present? */
                                222         [ #  # ]:              0 :     if (((PageHeader) page)->pd_lower >= MAXALIGN(SizeOfPageHeaderData) +
                                223                 :                :         offsetof(GISTDeletedPageContents, deleteXid) + sizeof(FullTransactionId))
                                224                 :                :     {
                                225                 :              0 :         return ((GISTDeletedPageContents *) PageGetContents(page))->deleteXid;
                                226                 :                :     }
                                227                 :                :     else
                                228                 :              0 :         return FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId);
                                229                 :                : }
                                230                 :                : 
                                231                 :                : /*
                                232                 :                :  * Vector of GISTENTRY structs; user-defined methods union and picksplit
                                233                 :                :  * take it as one of their arguments
                                234                 :                :  */
                                235                 :                : typedef struct
                                236                 :                : {
                                237                 :                :     int32       n;              /* number of elements */
                                238                 :                :     GISTENTRY   vector[FLEXIBLE_ARRAY_MEMBER];
                                239                 :                : } GistEntryVector;
                                240                 :                : 
                                241                 :                : #define GEVHDRSZ    (offsetof(GistEntryVector, vector))
                                242                 :                : 
                                243                 :                : /*
                                244                 :                :  * macro to initialize a GISTENTRY
                                245                 :                :  */
                                246                 :                : #define gistentryinit(e, k, r, pg, o, l) \
                                247                 :                :     do { (e).key = (k); (e).rel = (r); (e).page = (pg); \
                                248                 :                :          (e).offset = (o); (e).leafkey = (l); } while (0)
                                249                 :                : 
                                250                 :                : extern StrategyNumber GistTranslateStratnum(Oid opclass, StrategyNumber strat);
                                251                 :                : 
                                252                 :                : #endif                          /* GIST_H */
        

Generated by: LCOV version 2.1-beta2-3-g6141622