From c17bcea12ea0ffc94b65dd837db0e664743ff4de Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Wed, 27 Jun 2018 11:18:01 +1200 Subject: [PATCH] Use a dlist for unowned relations. Previously we used an open-coded singly-linked list, which required remove_from_unowned_list() to perform an O(n) search. Make it O(1). Author: Thomas Munro Discussion: https://postgr.es/m/CAHGQGwHVQkdfDqtvGVkty+19cQakAydXn1etGND3X0PHbZ3+6w@mail.gmail.com --- src/backend/storage/smgr/smgr.c | 44 +++++++++------------------------ src/include/storage/smgr.h | 3 ++- 2 files changed, 14 insertions(+), 33 deletions(-) diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index 08f06bade25..1388557c1ba 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -18,6 +18,7 @@ #include "postgres.h" #include "commands/tablespace.h" +#include "lib/ilist.h" #include "storage/bufmgr.h" #include "storage/ipc.h" #include "storage/smgr.h" @@ -82,7 +83,7 @@ static const int NSmgr = lengthof(smgrsw); */ static HTAB *SMgrRelationHash = NULL; -static SMgrRelation first_unowned_reln = NULL; +static dlist_head unowned_relns; /* local function prototypes */ static void smgrshutdown(int code, Datum arg); @@ -150,7 +151,7 @@ smgropen(RelFileNode rnode, BackendId backend) ctl.entrysize = sizeof(SMgrRelationData); SMgrRelationHash = hash_create("smgr relation table", 400, &ctl, HASH_ELEM | HASH_BLOBS); - first_unowned_reln = NULL; + dlist_init(&unowned_relns); } /* Look up or create an entry */ @@ -236,16 +237,11 @@ smgrclearowner(SMgrRelation *owner, SMgrRelation reln) /* * add_to_unowned_list -- link an SMgrRelation onto the unowned list - * - * Check remove_from_unowned_list()'s comments for performance - * considerations. */ static void add_to_unowned_list(SMgrRelation reln) { - /* place it at head of the list (to make smgrsetowner cheap) */ - reln->next_unowned_reln = first_unowned_reln; - first_unowned_reln = reln; + dlist_push_head(&unowned_relns, &reln->unowned_node); } /* @@ -253,31 +249,11 @@ add_to_unowned_list(SMgrRelation reln) * * If the reln is not present in the list, nothing happens. Typically this * would be caller error, but there seems no reason to throw an error. - * - * In the worst case this could be rather slow; but in all the cases that seem - * likely to be performance-critical, the reln being sought will actually be - * first in the list. Furthermore, the number of unowned relns touched in any - * one transaction shouldn't be all that high typically. So it doesn't seem - * worth expending the additional space and management logic needed for a - * doubly-linked list. */ static void remove_from_unowned_list(SMgrRelation reln) { - SMgrRelation *link; - SMgrRelation cur; - - for (link = &first_unowned_reln, cur = *link; - cur != NULL; - link = &cur->next_unowned_reln, cur = *link) - { - if (cur == reln) - { - *link = cur->next_unowned_reln; - cur->next_unowned_reln = NULL; - break; - } - } + dlist_delete(&reln->unowned_node); } /* @@ -797,13 +773,17 @@ smgrpostckpt(void) void AtEOXact_SMgr(void) { + SMgrRelation reln; + dlist_mutable_iter iter; + /* * Zap all unowned SMgrRelations. We rely on smgrclose() to remove each * one from the list. */ - while (first_unowned_reln != NULL) + dlist_foreach_modify(iter, &unowned_relns) { - Assert(first_unowned_reln->smgr_owner == NULL); - smgrclose(first_unowned_reln); + reln = dlist_container(SMgrRelationData, unowned_node, iter.cur); + Assert(reln->smgr_owner == NULL); + smgrclose(reln); } } diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index 558e4d8518b..275fc6ce419 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -15,6 +15,7 @@ #define SMGR_H #include "fmgr.h" +#include "lib/ilist.h" #include "storage/block.h" #include "storage/relfilenode.h" @@ -72,7 +73,7 @@ typedef struct SMgrRelationData struct _MdfdVec *md_seg_fds[MAX_FORKNUM + 1]; /* if unowned, list link in list of all unowned SMgrRelations */ - struct SMgrRelationData *next_unowned_reln; + dlist_node unowned_node; } SMgrRelationData; typedef SMgrRelationData *SMgrRelation; -- 2.17.0