Skip to content

Commit 8d25663

Browse files
rscharfegitster
authored andcommitted
mem-pool: add mem_pool_strfmt()
Add a function for building a string, printf style, using a memory pool. It uses the free space in the current block in the first attempt. If that suffices then the result can already be used without copying or reformatting. For strings that are significantly shorter on average than the block size (ca. 1 MiB by default) this is the case most of the time, leading to a better perfomance than a solution that doesn't access mem-pool internals. Signed-off-by: René Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3c2a3fd commit 8d25663

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

mem-pool.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,45 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len)
107107
return r;
108108
}
109109

110+
static char *mem_pool_strvfmt(struct mem_pool *pool, const char *fmt,
111+
va_list ap)
112+
{
113+
struct mp_block *block = pool->mp_block;
114+
char *next_free = block ? block->next_free : NULL;
115+
size_t available = block ? block->end - block->next_free : 0;
116+
va_list cp;
117+
int len, len2;
118+
char *ret;
119+
120+
va_copy(cp, ap);
121+
len = vsnprintf(next_free, available, fmt, cp);
122+
va_end(cp);
123+
if (len < 0)
124+
BUG("your vsnprintf is broken (returned %d)", len);
125+
126+
ret = mem_pool_alloc(pool, len + 1); /* 1 for NUL */
127+
128+
/* Shortcut; relies on mem_pool_alloc() not touching buffer contents. */
129+
if (ret == next_free)
130+
return ret;
131+
132+
len2 = vsnprintf(ret, len + 1, fmt, ap);
133+
if (len2 != len)
134+
BUG("your vsnprintf is broken (returns inconsistent lengths)");
135+
return ret;
136+
}
137+
138+
char *mem_pool_strfmt(struct mem_pool *pool, const char *fmt, ...)
139+
{
140+
va_list ap;
141+
char *ret;
142+
143+
va_start(ap, fmt);
144+
ret = mem_pool_strvfmt(pool, fmt, ap);
145+
va_end(ap);
146+
return ret;
147+
}
148+
110149
void *mem_pool_calloc(struct mem_pool *pool, size_t count, size_t size)
111150
{
112151
size_t len = st_mult(count, size);

mem-pool.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ void *mem_pool_calloc(struct mem_pool *pool, size_t count, size_t size);
4747
char *mem_pool_strdup(struct mem_pool *pool, const char *str);
4848
char *mem_pool_strndup(struct mem_pool *pool, const char *str, size_t len);
4949

50+
/*
51+
* Allocate memory from the memory pool and format a string into it.
52+
*/
53+
char *mem_pool_strfmt(struct mem_pool *pool, const char *fmt, ...);
54+
5055
/*
5156
* Move the memory associated with the 'src' pool to the 'dst' pool. The 'src'
5257
* pool will be empty and not contain any memory. It still needs to be free'd

0 commit comments

Comments
 (0)