Skip to content

Commit 064ac71

Browse files
UTIL: sss_create_internal_fqname() optimization (caching)
This helper is heavily used, including in hot paths. Since number of domains used is very limited, hash table used for caching should be very small and lookup much more efficient as compared with `sss_tc_utf8_str_tolower()`
1 parent 3c854da commit 064ac71

File tree

1 file changed

+54
-8
lines changed

1 file changed

+54
-8
lines changed

src/util/usertools.c

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -638,29 +638,75 @@ errno_t sss_parse_internal_fqname(TALLOC_CTX *mem_ctx,
638638
return EOK;
639639
}
640640

641+
/* This is a wrapper around `sss_tc_utf8_str_tolower()` that
642+
* maintains run time cache.
643+
*/
644+
static const char *sss_get_lc_dom_name(const char *dom_name)
645+
{
646+
static TALLOC_CTX *cache_ctx;
647+
static hash_table_t *lc_dom_name_cache;
648+
hash_key_t key;
649+
hash_value_t value;
650+
char *lc_dom_name;
651+
int hret;
652+
653+
key.type = HASH_KEY_STRING;
654+
key.str = discard_const(dom_name);
655+
656+
if (lc_dom_name_cache != NULL) {
657+
hret = hash_lookup(lc_dom_name_cache, &key, &value);
658+
if (hret == HASH_SUCCESS) {
659+
return (const char *)value.ptr;
660+
}
661+
} else {
662+
cache_ctx = talloc_new(NULL);
663+
if (!cache_ctx) return NULL;
664+
hret = hash_create(0, &lc_dom_name_cache, NULL, NULL);
665+
if (hret != HASH_SUCCESS) {
666+
DEBUG(SSSDBG_CRIT_FAILURE,
667+
"hash_create() failed [%s]\n", hash_error_string(hret));
668+
return NULL;
669+
}
670+
}
671+
672+
lc_dom_name = sss_tc_utf8_str_tolower(cache_ctx, dom_name);
673+
if (lc_dom_name == NULL) {
674+
return NULL;
675+
}
676+
677+
value.type = HASH_VALUE_PTR;
678+
value.ptr = lc_dom_name;
679+
680+
hret = hash_enter(lc_dom_name_cache, &key, &value);
681+
if (hret != HASH_SUCCESS) {
682+
DEBUG(SSSDBG_CRIT_FAILURE,
683+
"hash_enter() failed [%s]\n", hash_error_string(hret));
684+
talloc_free(lc_dom_name);
685+
return NULL;
686+
}
687+
688+
return lc_dom_name;
689+
}
690+
641691
/* Creates internal fqname in format shortname@domname.
642692
* The domain portion is lowercased. */
643693
char *sss_create_internal_fqname(TALLOC_CTX *mem_ctx,
644694
const char *shortname,
645695
const char *dom_name)
646696
{
647-
char *lc_dom_name;
648-
char *fqname = NULL;
697+
const char *lc_dom_name;
649698

650699
if (shortname == NULL || dom_name == NULL) {
651700
/* Avoid allocating null@null */
652701
return NULL;
653702
}
654703

655-
lc_dom_name = sss_tc_utf8_str_tolower(mem_ctx, dom_name);
704+
lc_dom_name = sss_get_lc_dom_name(dom_name);
656705
if (lc_dom_name == NULL) {
657-
goto done;
706+
return NULL;
658707
}
659708

660-
fqname = talloc_asprintf(mem_ctx, "%s@%s", shortname, lc_dom_name);
661-
talloc_free(lc_dom_name);
662-
done:
663-
return fqname;
709+
return talloc_asprintf(mem_ctx, "%s@%s", shortname, lc_dom_name);
664710
}
665711

666712
/* Creates a list of internal fqnames in format shortname@domname.

0 commit comments

Comments
 (0)