Inline ginCompareItemPointers function for speed.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sat, 29 Jun 2013 09:54:02 +0000 (12:54 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sat, 29 Jun 2013 09:55:34 +0000 (12:55 +0300)
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
src/include/access/gin_private.h

index 13ab44869232d1ea73726dcc1ee21f499dc27c61..f017de0cdc8c1c257a2f8d36a7ddd82cb8a689f2 100644 (file)
 #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.
index 1868b77df100d50555fb8cfea185956f8b5f889b..c603521c9574fda6331889c5034ac956f86b2cff 100644 (file)
@@ -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 */