diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2022-10-14 12:26:39 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2022-10-14 12:26:39 -0400 |
commit | 3057465acfbea2f3dd7a914a1478064022c6eecd (patch) | |
tree | 63de056985ef04bedf14c1baab0c53ebb3f7c326 /src/backend/utils/misc/guc_funcs.c | |
parent | 407b50f2d421bca5b134a0033176ea8f8c68dc6b (diff) | |
download | postgresql-3057465acfbea2f3dd7a914a1478064022c6eecd.tar.gz postgresql-3057465acfbea2f3dd7a914a1478064022c6eecd.zip |
Replace the sorted array of GUC variables with a hash table.
This gets rid of bsearch() in favor of hashed lookup. The main
advantage is that it becomes far cheaper to add new GUCs, since
we needn't re-sort the pointer array. Adding N new GUCs had
been O(N^2 log N), but now it's closer to O(N). We need to
sort only in SHOW ALL and equivalent functions, which are
hopefully not performance-critical to anybody.
Also, merge GetNumConfigOptions() into get_guc_variables(),
because in a world where the set of GUCs isn't fairly static
you really want to consider those two results as tied together
not independent.
Discussion: https://postgr.es/m/2982579.1662416866@sss.pgh.pa.us
Diffstat (limited to 'src/backend/utils/misc/guc_funcs.c')
-rw-r--r-- | src/backend/utils/misc/guc_funcs.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/src/backend/utils/misc/guc_funcs.c b/src/backend/utils/misc/guc_funcs.c index ffc71726f91..fb763df5fe8 100644 --- a/src/backend/utils/misc/guc_funcs.c +++ b/src/backend/utils/misc/guc_funcs.c @@ -455,13 +455,15 @@ ShowGUCConfigOption(const char *name, DestReceiver *dest) static void ShowAllGUCConfig(DestReceiver *dest) { - int i; + struct config_generic **guc_vars; + int num_vars; TupOutputState *tstate; TupleDesc tupdesc; Datum values[3]; bool isnull[3] = {false, false, false}; - struct config_generic **guc_variables = get_guc_variables(); - int num_guc_variables = GetNumConfigOptions(); + + /* collect the variables, in sorted order */ + guc_vars = get_guc_variables(&num_vars); /* need a tuple descriptor representing three TEXT columns */ tupdesc = CreateTemplateTupleDesc(3); @@ -475,9 +477,9 @@ ShowAllGUCConfig(DestReceiver *dest) /* prepare for projection of tuples */ tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual); - for (i = 0; i < num_guc_variables; i++) + for (int i = 0; i < num_vars; i++) { - struct config_generic *conf = guc_variables[i]; + struct config_generic *conf = guc_vars[i]; char *setting; if ((conf->flags & GUC_NO_SHOW_ALL) || @@ -570,20 +572,13 @@ pg_settings_get_flags(PG_FUNCTION_ARGS) } /* - * Return GUC variable value by variable number; optionally return canonical - * form of name. Return value is palloc'd. + * Extract fields to show in pg_settings for given variable. */ static void -GetConfigOptionByNum(int varnum, const char **values, bool *noshow) +GetConfigOptionValues(struct config_generic *conf, const char **values, + bool *noshow) { char buffer[256]; - struct config_generic *conf; - struct config_generic **guc_variables = get_guc_variables(); - - /* check requested variable number valid */ - Assert((varnum >= 0) && (varnum < GetNumConfigOptions())); - - conf = guc_variables[varnum]; if (noshow) { @@ -849,6 +844,8 @@ Datum show_all_settings(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; + struct config_generic **guc_vars; + int num_vars; TupleDesc tupdesc; int call_cntr; int max_calls; @@ -913,8 +910,14 @@ show_all_settings(PG_FUNCTION_ARGS) attinmeta = TupleDescGetAttInMetadata(tupdesc); funcctx->attinmeta = attinmeta; + /* collect the variables, in sorted order */ + guc_vars = get_guc_variables(&num_vars); + + /* use user_fctx to remember the array location */ + funcctx->user_fctx = guc_vars; + /* total number of tuples to be returned */ - funcctx->max_calls = GetNumConfigOptions(); + funcctx->max_calls = num_vars; MemoryContextSwitchTo(oldcontext); } @@ -922,6 +925,7 @@ show_all_settings(PG_FUNCTION_ARGS) /* stuff done on every call of the function */ funcctx = SRF_PERCALL_SETUP(); + guc_vars = (struct config_generic **) funcctx->user_fctx; call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; attinmeta = funcctx->attinmeta; @@ -938,7 +942,8 @@ show_all_settings(PG_FUNCTION_ARGS) */ do { - GetConfigOptionByNum(call_cntr, (const char **) values, &noshow); + GetConfigOptionValues(guc_vars[call_cntr], (const char **) values, + &noshow); if (noshow) { /* bump the counter and get the next config setting */ |