public inbox for [email protected]
help / color / mirror / Atom feedFrom: Justin Pryzby <[email protected]>
Subject: [PATCH v6 3/4] Convert data structure to use a list
Date: Wed, 4 Mar 2020 17:38:03 -0600
---
src/backend/utils/adt/genfile.c | 78 +++++++++++++++++----------------
1 file changed, 41 insertions(+), 37 deletions(-)
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index c5148f547b..bc473e79ef 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -37,8 +37,9 @@
typedef struct
{
- char *location;
- DIR *dirdesc;
+ /* List of opened dirs */
+ List *location;
+ List *dirdesc;
bool include_dot_dirs;
/* Used in ls_dir_files: */
@@ -474,10 +475,9 @@ pg_ls_dir(PG_FUNCTION_ARGS)
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
fctx = palloc(sizeof(directory_fctx));
- fctx->location = convert_and_check_filename(PG_GETARG_TEXT_PP(0));
-
+ fctx->location = lappend(NIL, convert_and_check_filename(PG_GETARG_TEXT_PP(0)));
+ fctx->dirdesc = lappend(NIL, AllocateDir(linitial(fctx->location)));
fctx->include_dot_dirs = include_dot_dirs;
- fctx->dirdesc = AllocateDir(fctx->location);
if (!fctx->dirdesc)
{
@@ -490,7 +490,7 @@ pg_ls_dir(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not open directory \"%s\": %m",
- fctx->location)));
+ (char*)linitial(fctx->location))));
}
funcctx->user_fctx = fctx;
MemoryContextSwitchTo(oldcontext);
@@ -499,7 +499,7 @@ pg_ls_dir(PG_FUNCTION_ARGS)
funcctx = SRF_PERCALL_SETUP();
fctx = (directory_fctx *) funcctx->user_fctx;
- while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
+ while ((de = ReadDir(linitial(fctx->dirdesc), linitial(fctx->location))) != NULL)
{
if (!fctx->include_dot_dirs &&
(strcmp(de->d_name, ".") == 0 ||
@@ -509,7 +509,9 @@ pg_ls_dir(PG_FUNCTION_ARGS)
SRF_RETURN_NEXT(funcctx, CStringGetTextDatum(de->d_name));
}
- FreeDir(fctx->dirdesc);
+ FreeDir(linitial(fctx->dirdesc));
+ list_free(fctx->dirdesc);
+ list_free_deep(fctx->location);
SRF_RETURN_DONE(funcctx);
}
@@ -528,20 +530,25 @@ pg_ls_dir_1arg(PG_FUNCTION_ARGS)
}
/*
- * Populate fctx with list of pathnames and stat structues. Generate a full
- * list of the stat structures all at once - the alternative is to re-stat
- * everything later on, which then requires somehow handling cases like the 2nd
- * stat fails, or the 2nd stat returns a dir which didn't exist at the time we
- * originally looked, or existed but wasn't a dir. stat()ing everything all at
- * once gets as close as we can to a consistent view of the filesystem, from
- * which files might be removed or renamed or reordered.
+ * Populate fctx with list of pathnames and stat structues.
+ *
+ * Generate a full list of the stat structures all at once. That gets as close
+ * as we can to a consistent view of the filesystem, from which files might be
+ * removed or renamed or reordered.
+ *
+ * recurse is the recursion level into a stack of dirs, or -1 to not decend
+ * into directories.
*/
static void
-populate_paths(directory_fctx *fctx, bool recurse)
+populate_paths(directory_fctx *fctx, int recurse)
{
struct dirent *de;
struct stat attrib;
- while ((de = ReadDir(fctx->dirdesc, fctx->location)) != NULL)
+
+ DIR *dirdesc = llast(fctx->dirdesc);
+ char *location = llast(fctx->location);
+
+ while ((de = ReadDir(dirdesc, location)) != NULL)
{
char path[MAXPGPATH];
@@ -550,28 +557,23 @@ populate_paths(directory_fctx *fctx, bool recurse)
continue;
/* Get the file info */
- snprintf(path, sizeof(path), "%s/%s", fctx->location, de->d_name);
+ snprintf(path, sizeof(path), "%s/%s", location, de->d_name);
if (stat(path, &attrib) < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not stat file \"%s\": %m", path)));
/* Ignore anything but regular files, or dirs, if requested */
- if (S_ISDIR(attrib.st_mode))
+ if (recurse == -1)
+ ; /* Do nothing, fall through */
+ else if (S_ISDIR(attrib.st_mode))
{
- /* Save current dir while recursing */
- directory_fctx oldfctx = *fctx;
-
- fctx->location = path;
- fctx->dirdesc = AllocateDir(path);
-
- if (recurse)
- populate_paths(fctx, recurse);
-
- /* Restore previous dir */
- FreeDir(fctx->dirdesc);
- fctx->dirdesc = oldfctx.dirdesc;
- fctx->location = oldfctx.location;
+ /* Reallocate location and dirdesc whenever recursing */
+ fctx->location = lappend(fctx->location, path);
+ fctx->dirdesc = lappend(fctx->dirdesc, AllocateDir(path));
+ populate_paths(fctx, 1+recurse);
+ FreeDir(llast(fctx->dirdesc));
+ list_delete_last(fctx->dirdesc);
} else if (!S_ISREG(attrib.st_mode))
continue;
@@ -619,8 +621,8 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok, bool
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
- fctx->location = pstrdup(dir);
- fctx->dirdesc = AllocateDir(fctx->location);
+ fctx->location = lappend(NIL, pstrdup(dir));
+ fctx->dirdesc = lappend(NIL, AllocateDir(dir));
fctx->npaths = 0;
fctx->path = palloc(sizeof(*fctx->path));
fctx->stat = palloc(sizeof(*fctx->stat));
@@ -636,10 +638,10 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok, bool
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not open directory \"%s\": %m",
- fctx->location)));
+ dir)));
}
- populate_paths(fctx, dir_ok);
+ populate_paths(fctx, dir_ok ? 0 : -1);
funcctx->max_calls = fctx->npaths;
funcctx->user_fctx = fctx;
MemoryContextSwitchTo(oldcontext);
@@ -674,7 +676,9 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok, bool
pfree(fctx->path);
pfree(fctx->stat);
- FreeDir(fctx->dirdesc);
+ FreeDir(linitial(fctx->dirdesc));
+ list_free(fctx->dirdesc);
+ list_free(fctx->location);
SRF_RETURN_DONE(funcctx);
}
--
2.17.0
--V88s5gaDVPzZ0KCq
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="v6-0004-Read-each-dir-incrementally-during-each-SRF-call.patch"
view thread (31+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH v6 3/4] Convert data structure to use a list
In-Reply-To: <no-message-id-1882414@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox