From ee6556555b237c0feeb175e7ea7ce23af959e7ba Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Sat, 29 Jun 2013 12:54:02 +0300 Subject: [PATCH] Inline ginCompareItemPointers function for speed. ginCompareItemPointers function is called heavily in gin index scans - inlining it speeds up some kind of queries a lot. --- src/backend/access/gin/gindatapage.c | 19 ------------------- src/include/access/gin_private.h | 25 ++++++++++++++++++++++++- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c index 13ab448692..f017de0cdc 100644 --- a/src/backend/access/gin/gindatapage.c +++ b/src/backend/access/gin/gindatapage.c @@ -17,25 +17,6 @@ #include "access/gin_private.h" #include "utils/rel.h" -int -ginCompareItemPointers(ItemPointer a, ItemPointer b) -{ - BlockNumber ba = GinItemPointerGetBlockNumber(a); - BlockNumber bb = GinItemPointerGetBlockNumber(b); - - if (ba == bb) - { - OffsetNumber oa = GinItemPointerGetOffsetNumber(a); - OffsetNumber ob = GinItemPointerGetOffsetNumber(b); - - if (oa == ob) - return 0; - return (oa > ob) ? 1 : -1; - } - - return (ba > bb) ? 1 : -1; -} - /* * Merge two ordered arrays of itempointers, eliminating any duplicates. * Returns the number of items in the result. diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index 1868b77df1..c603521c95 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -530,7 +530,6 @@ extern void ginEntryFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rb extern IndexTuple ginPageGetLinkItup(Buffer buf); /* gindatapage.c */ -extern int ginCompareItemPointers(ItemPointer a, ItemPointer b); extern uint32 ginMergeItemPointers(ItemPointerData *dst, ItemPointerData *a, uint32 na, ItemPointerData *b, uint32 nb); @@ -724,4 +723,28 @@ extern void ginHeapTupleFastCollect(GinState *ginstate, extern void ginInsertCleanup(GinState *ginstate, bool vac_delay, IndexBulkDeleteResult *stats); +/* + * Merging the results of several gin scans compares item pointers a lot, + * so we want this to be inlined. But if the compiler doesn't support that, + * fall back on the non-inline version from itemptr.c. See STATIC_IF_INLINE in + * c.h. + */ +#ifdef PG_USE_INLINE +static inline int +ginCompareItemPointers(ItemPointer a, ItemPointer b) +{ + uint64 ia = (uint64) a->ip_blkid.bi_hi << 32 | (uint64) a->ip_blkid.bi_lo << 16 | a->ip_posid; + uint64 ib = (uint64) b->ip_blkid.bi_hi << 32 | (uint64) b->ip_blkid.bi_lo << 16 | b->ip_posid; + + if (ia == ib) + return 0; + else if (ia > ib) + return 1; + else + return -1; +} +#else +#define ginCompareItemPointers(a, b) ItemPointerCompare(a, b) +#endif /* PG_USE_INLINE */ + #endif /* GIN_PRIVATE_H */ -- GitLab