From f5ae3ba4828ece02bae2d16b4cbce847fbcea850 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Fri, 16 Jan 2015 17:47:59 +0100 Subject: [PATCH] Make tbm_add_tuples more efficient by caching the last acccessed page. When adding a large number of tuples to a TID bitmap using tbm_add_tuples() sometimes a lot of time was spent looking up a page's entry in the bitmap's internal hashtable. Improve efficiency by caching the last accessed page, while iterating over the passed in tuples, hoping consecutive tuples will often be on the same page. In many cases that's a good bet, and in the rest the added overhead isn't big. Discussion: 54479A85.8060309@sigaev.ru Author: Teodor Sigaev Reviewed-By: David Rowley --- src/backend/nodes/tidbitmap.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c index d8248b1832..dd1c6657fa 100644 --- a/src/backend/nodes/tidbitmap.c +++ b/src/backend/nodes/tidbitmap.c @@ -268,14 +268,14 @@ void tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids, bool recheck) { - int i; + int i; + PagetableEntry *page = NULL; Assert(!tbm->iterating); for (i = 0; i < ntids; i++) { BlockNumber blk = ItemPointerGetBlockNumber(tids + i); OffsetNumber off = ItemPointerGetOffsetNumber(tids + i); - PagetableEntry *page; int wordnum, bitnum; @@ -283,10 +283,18 @@ tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids, if (off < 1 || off > MAX_TUPLES_PER_PAGE) elog(ERROR, "tuple offset out of range: %u", off); - if (tbm_page_is_lossy(tbm, blk)) - continue; /* whole page is already marked */ + if (page == NULL || page->blockno != blk) + { + if (tbm_page_is_lossy(tbm, blk)) + continue; /* whole page is already marked */ - page = tbm_get_pageentry(tbm, blk); + /* + * Cache this page as it's quite likely that we'll see the same + * page again in the next iteration. This will save having to + * lookup the page in the hashtable again. + */ + page = tbm_get_pageentry(tbm, blk); + } if (page->ischunk) { @@ -303,7 +311,11 @@ tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids, page->recheck |= recheck; if (tbm->nentries > tbm->maxentries) + { tbm_lossify(tbm); + /* Cached page could become lossy or freed */ + page = NULL; + } } }