summaryrefslogtreecommitdiffstats
path: root/source3/lib/util_str.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/util_str.c')
-rw-r--r--source3/lib/util_str.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 967beda1c5d..908f23aaa9d 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -1294,3 +1294,42 @@ char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
TALLOC_FREE(s);
return list;
}
+
+/*
+ * This routine improves performance for operations temporarily acting on a
+ * full path. It is equivalent to the much more expensive
+ *
+ * talloc_asprintf(talloc_tos(), "%s/%s", dir, name)
+ *
+ * This actually does make a difference in metadata-heavy workloads (i.e. the
+ * "standard" client.txt nbench run.
+ */
+
+ssize_t full_path_tos(const char *dir, const char *name,
+ char *tmpbuf, size_t tmpbuf_len,
+ char **pdst, char **to_free)
+{
+ size_t dirlen, namelen, len;
+ char *dst;
+
+ dirlen = strlen(dir);
+ namelen = strlen(name);
+ len = dirlen + namelen + 1;
+
+ if (len < tmpbuf_len) {
+ dst = tmpbuf;
+ *to_free = NULL;
+ } else {
+ dst = talloc_array(talloc_tos(), char, len+1);
+ if (dst == NULL) {
+ return -1;
+ }
+ *to_free = dst;
+ }
+
+ memcpy(dst, dir, dirlen);
+ dst[dirlen] = '/';
+ memcpy(dst+dirlen+1, name, namelen+1);
+ *pdst = dst;
+ return len;
+}