nstr: avoid double allocation

String contents are stored immediately after the
struct _neo_nstr in memory now.
This commit is contained in:
anna 2021-07-22 13:42:14 +02:00
parent c797540dbc
commit 3040b09669
Signed by: fef
GPG key ID: EC22E476DC2D3D84
2 changed files with 17 additions and 18 deletions

View file

@ -21,7 +21,7 @@ struct _neo_nstr_init_info {
* *
* The string will be initialized before `main` is called. * The string will be initialized before `main` is called.
* *
* @param name: Name of the `string *` variable to be declared * @param name: Name of the `nstr_t *` variable to be declared
* @param content: A `const char *` with the contents of the string * @param content: A `const char *` with the contents of the string
*/ */
#define NSTR_DEFINE(name, content) \ #define NSTR_DEFINE(name, content) \
@ -166,8 +166,8 @@ int nstrcmp(const nstr_t *s1, const nstr_t *s2, error *err);
* If either of the two string are `nil` or acquiring a lock on them fails, * If either of the two string are `nil` or acquiring a lock on them fails,
* an error is yeeted. * an error is yeeted.
* *
* @param s1: First `string *` * @param s1: First `nstr_t *`
* @param s2: Second `string *` * @param s2: Second `nstr_t *`
* @param err: Error pointer * @param err: Error pointer
* @returns Whether the two strings are equal, unless an error occurred * @returns Whether the two strings are equal, unless an error occurred
*/ */
@ -190,17 +190,17 @@ nstr_t *leftpad(const nstr_t *s, usize length, nchar fill, error *err);
/** /**
* Iterate over each character in a string. * Iterate over each character in a string.
* *
* @param nstr: `string *` to iterate over * @param cursor: `nchar *` to store the current character in
* @param nchr: `nchar *` to store the current character in * @param nstr: `nstr_t *` to iterate over
* @param err: Error pointer; the loop will terminate early if an uncaught * @param err: Error pointer; the loop will terminate early if an uncaught
* error occurred * error occurred
*/ */
#define nstr_foreach_nchr(nstr, nchr, err) \ #define nstr_foreach(cursor, nstr, err) \
for (const char *__pos = \ for (const char *__pos = \
(nstr)->_data + utf8_to_nchr(nchr, (nstr)->_data, err); \ (nstr)->_data + utf8_to_nchr(cursor, (nstr)->_data, err); \
*__pos != '\0' && (err) != nil && \ /* errput sets the error number to 0xffffffff, thus number + 1 */ \
(err)->_number + 1 < 2; \ *__pos != '\0' && (err) != nil && (err)->_number + 1 < 2; \
__pos += utf8_to_nchr(nchr, __pos, err)) __pos += utf8_to_nchr(cursor, __pos, err))
/* /*
* This file is part of libneo. * This file is part of libneo.

View file

@ -16,7 +16,6 @@
static void nstr_destroy(nstr_t *str) static void nstr_destroy(nstr_t *str)
{ {
nfree(str->_data);
nfree(str); nfree(str);
} }
@ -27,11 +26,6 @@ static nstr_t *nstr_unsafe(const char *restrict s, usize size_without_nul, error
return nil; return nil;
} }
nstr_t *str = nalloc(sizeof(*str), err);
catch(err) {
return nil;
}
/* /*
* neo strings are terminated by four NUL characters rather than just * neo strings are terminated by four NUL characters rather than just
* one. We do this to make sure nothing bad can happen if some stupid * one. We do this to make sure nothing bad can happen if some stupid
@ -45,12 +39,17 @@ static nstr_t *nstr_unsafe(const char *restrict s, usize size_without_nul, error
* Yeah, this is definitely never gonna break my legs. * Yeah, this is definitely never gonna break my legs.
*/ */
str->_data = nalloc(size_without_nul + 4, err); nstr_t *str = nalloc(sizeof(*str) + size_without_nul + 4, err);
catch(err) { catch(err) {
nfree(str);
return nil; return nil;
} }
/*
* To improve locality and lower fragmentation, the actual data is
* stored immediately after the string itself. This also saves us an
* additional memory allocation.
*/
str->_data = (char *)str + sizeof(*str);
str->_len = len; str->_len = len;
str->_size = size_without_nul + 4; str->_size = size_without_nul + 4;
nref_init(str, nstr_destroy); nref_init(str, nstr_destroy);