aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/storage/smgr/md.c8
-rw-r--r--src/backend/storage/smgr/smgr.c74
-rw-r--r--src/include/storage/smgr.h3
3 files changed, 20 insertions, 65 deletions
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index f28a3e6d066..58a6e0f4ddc 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -1681,13 +1681,7 @@ DropRelationFiles(RelFileNode *delrels, int ndelrels, bool isRedo)
smgrdounlinkall(srels, ndelrels, isRedo);
- /*
- * Call smgrclose() in reverse order as when smgropen() is called.
- * This trick enables remove_from_unowned_list() in smgrclose()
- * to search the SMgrRelation from the unowned list,
- * with O(1) performance.
- */
- for (i = ndelrels - 1; i >= 0; i--)
+ for (i = 0; i < ndelrels; i++)
smgrclose(srels[i]);
pfree(srels);
}
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index 244b4ea72c8..c3da4277418 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"
@@ -80,12 +81,10 @@ 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);
-static void add_to_unowned_list(SMgrRelation reln);
-static void remove_from_unowned_list(SMgrRelation reln);
/*
@@ -148,7 +147,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 */
@@ -175,7 +174,7 @@ smgropen(RelFileNode rnode, BackendId backend)
reln->md_fd[forknum] = NULL;
/* it has no owner yet */
- add_to_unowned_list(reln);
+ dlist_push_tail(&unowned_relns, &reln->node);
}
return reln;
@@ -205,7 +204,7 @@ smgrsetowner(SMgrRelation *owner, SMgrRelation reln)
if (reln->smgr_owner)
*(reln->smgr_owner) = NULL;
else
- remove_from_unowned_list(reln);
+ dlist_delete(&reln->node);
/* Now establish the ownership relationship. */
reln->smgr_owner = owner;
@@ -229,53 +228,8 @@ smgrclearowner(SMgrRelation *owner, SMgrRelation reln)
/* unset our reference to the owner */
reln->smgr_owner = NULL;
- add_to_unowned_list(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;
-}
-
-/*
- * remove_from_unowned_list -- unlink an SMgrRelation from the unowned list
- *
- * 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;
- }
- }
+ /* add to list of unowned relations */
+ dlist_push_tail(&unowned_relns, &reln->node);
}
/*
@@ -302,7 +256,7 @@ smgrclose(SMgrRelation reln)
owner = reln->smgr_owner;
if (!owner)
- remove_from_unowned_list(reln);
+ dlist_delete(&reln->node);
if (hash_search(SMgrRelationHash,
(void *) &(reln->smgr_rnode),
@@ -782,13 +736,19 @@ smgrpostckpt(void)
void
AtEOXact_SMgr(void)
{
+ 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);
+ SMgrRelation rel = dlist_container(SMgrRelationData, node,
+ iter.cur);
+
+ Assert(rel->smgr_owner == NULL);
+
+ smgrclose(rel);
}
}
diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h
index dfb7e98e932..35c78ef6f25 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"
@@ -68,7 +69,7 @@ typedef struct SMgrRelationData
struct _MdfdVec *md_fd[MAX_FORKNUM + 1];
/* if unowned, list link in list of all unowned SMgrRelations */
- struct SMgrRelationData *next_unowned_reln;
+ dlist_node node;
} SMgrRelationData;
typedef SMgrRelationData *SMgrRelation;