commit a971a17d08f3ed3543a2240ffe771704730c4957
parent 2d94f506763c425a3ae41a6bd7c3ff3e72dffedf
Author: Remy Noulin <loader2x@gmail.com>
Date: Wed, 26 Jan 2022 14:24:14 +0200
add makeRoom macro and optimize readText function
release/libsheepy.c | 33 +++++++++++++++++++++++++--------
release/libsheepy.h | 24 +++++++++++++++++++++++-
src/libsheepy.c | 33 +++++++++++++++++++++++++--------
src/libsheepy.h | 24 +++++++++++++++++++++++-
4 files changed, 96 insertions(+), 18 deletions(-)
Diffstat:
4 files changed, 96 insertions(+), 18 deletions(-)
diff --git a/release/libsheepy.c b/release/libsheepy.c
@@ -9734,7 +9734,7 @@ char *intToS(int64_t n) {
char s[50];
char *r = NULL;
- sprintf(s, "%" PRIiMAX, n);
+ sprintf(s, "%" PRIi64, n);
r = strdup(s);
return(r);
}
@@ -9754,7 +9754,7 @@ char *bIntToS(char *s, int64_t n) {
if (!s) {
return(NULL);
}
- sprintf(s, "%" PRIiMAX, n);
+ sprintf(s, "%" PRIi64, n);
return(s);
}
@@ -49199,6 +49199,7 @@ char **listFromArrayS(char **array, size_t size) {
return(r);
}
+ // TODO allocate array size r for z to avoid reallocs and remove listPushS
// copy array content
for (size_t i = 0 ; i < size ; i++) {
if (array[i]) {
@@ -52889,7 +52890,7 @@ char **readText(const char *filePath) {
char **list = NULL;
// sanity checks
- if (!filePath) {
+ if (!filePath || isBlankS(filePath)) {
return(NULL);
}
fp = fopen(filePath, "r");
@@ -52900,6 +52901,13 @@ char **readText(const char *filePath) {
}
// read all lines
read = getline(&line, &len, fp);
+ size_t index = 0;
+ size_t alloc = sizeof(*list);
+ list = MALLOC(alloc);
+ if (!list) {
+ goto end;
+ }
+ *list = NULL;
while (read != -1) {
{
char* pos = NULL;
@@ -52907,15 +52915,24 @@ char **readText(const char *filePath) {
if (pos != NULL)
*pos = '\0';
}
- pErrorNULL(listPushS(&list, line));
+ size_t newsize = makeRoom((index+1) * sizeof(*list), alloc, sizeof(*list));
+ if (newsize != alloc) {
+ char **tmp = REALLOC(list, newsize);
+ if (!tmp) {
+ listFreeS(list);
+ list = NULL;
+ goto end;
+ }
+ alloc = newsize;
+ list = tmp;
+ }
+ list[index] = strdup(line);
+ list[++index] = NULL;
read = getline(&line, &len, fp);
}
+ end:
fclose(fp);
free(line);
- if (!list) {
- // nothing was read
- listEmptyS(list);
- }
return(list);
}
diff --git a/release/libsheepy.h b/release/libsheepy.h
@@ -98,7 +98,7 @@
// version accoring to the version package: Release.Major.minor.patch
// https://noulin.net/version/file/README.md.html
-#define LIBSHEEPY_VERSION "2.2.8"
+#define LIBSHEEPY_VERSION "2.2.8.1"
#ifndef SH_PREFIX
#define SH_PREFIX(NAME) NAME
@@ -1554,6 +1554,28 @@ extern uint64_t logMask;
// BINARY SEARCH END
+// makeRoom is dynamic memory allocation algorithm
+// given a length, an allocated size and the additionnal length,
+// makeRoom returns the new allocated size for realloc
+// when the new allocated size equals alloc value, there is no need to realloc the memory, enough space is already available
+#define libsheepyPrealloc (1024*1024)
+#define makeRoom(length, alloc, addlength) funcbegin\
+ typeof(alloc) r;\
+ typeof(alloc) newlen = (length) + (addlength);\
+ if (newlen < (alloc)) {\
+ r = alloc;\
+ } \
+ else {\
+ if (newlen < libsheepyPrealloc) {\
+ r = newlen * 2;\
+ }\
+ else {\
+ r = newlen + libsheepyPrealloc;\
+ }\
+ }\
+ r;\
+ funcend
+
// initialize libsheepy (optional, for debug)
typedef void(*initLibsheepyObjectP)(void);
void initLibsheepyF(const char *progPath, initLibsheepyObjectP initF);
diff --git a/src/libsheepy.c b/src/libsheepy.c
@@ -9790,7 +9790,7 @@ char *intToS(int64_t n) {
char s[50];
char *r = NULL;
- sprintf(s, "%" PRIiMAX, n);
+ sprintf(s, "%" PRIi64, n);
r = strdup(s);
return(r);
}
@@ -9810,7 +9810,7 @@ char *bIntToS(char *s, int64_t n) {
if (!s) {
return(NULL);
}
- sprintf(s, "%" PRIiMAX, n);
+ sprintf(s, "%" PRIi64, n);
return(s);
}
@@ -49255,6 +49255,7 @@ char **listFromArrayS(char **array, size_t size) {
return(r);
}
+ // TODO allocate array size r for z to avoid reallocs and remove listPushS
// copy array content
for (size_t i = 0 ; i < size ; i++) {
if (array[i]) {
@@ -52945,7 +52946,7 @@ char **readText(const char *filePath) {
char **list = NULL;
// sanity checks
- if (!filePath) {
+ if (!filePath || isBlankS(filePath)) {
return(NULL);
}
fp = fopen(filePath, "r");
@@ -52956,6 +52957,13 @@ char **readText(const char *filePath) {
}
// read all lines
read = getline(&line, &len, fp);
+ size_t index = 0;
+ size_t alloc = sizeof(*list);
+ list = MALLOC(alloc);
+ if (!list) {
+ goto end;
+ }
+ *list = NULL;
while (read != -1) {
{
char* pos = NULL;
@@ -52963,15 +52971,24 @@ char **readText(const char *filePath) {
if (pos != NULL)
*pos = '\0';
}
- pErrorNULL(listPushS(&list, line));
+ size_t newsize = makeRoom((index+1) * sizeof(*list), alloc, sizeof(*list));
+ if (newsize != alloc) {
+ char **tmp = REALLOC(list, newsize);
+ if (!tmp) {
+ listFreeS(list);
+ list = NULL;
+ goto end;
+ }
+ alloc = newsize;
+ list = tmp;
+ }
+ list[index] = strdup(line);
+ list[++index] = NULL;
read = getline(&line, &len, fp);
}
+ end:
fclose(fp);
free(line);
- if (!list) {
- // nothing was read
- listEmptyS(list);
- }
return(list);
}
diff --git a/src/libsheepy.h b/src/libsheepy.h
@@ -98,7 +98,7 @@
// version accoring to the version package: Release.Major.minor.patch
// https://noulin.net/version/file/README.md.html
-#define LIBSHEEPY_VERSION "2.2.8"
+#define LIBSHEEPY_VERSION "2.2.8.1"
#ifndef SH_PREFIX
#define SH_PREFIX(NAME) NAME
@@ -1554,6 +1554,28 @@ extern uint64_t logMask;
// BINARY SEARCH END
+// makeRoom is dynamic memory allocation algorithm
+// given a length, an allocated size and the additionnal length,
+// makeRoom returns the new allocated size for realloc
+// when the new allocated size equals alloc value, there is no need to realloc the memory, enough space is already available
+#define libsheepyPrealloc (1024*1024)
+#define makeRoom(length, alloc, addlength) funcbegin\
+ typeof(alloc) r;\
+ typeof(alloc) newlen = (length) + (addlength);\
+ if (newlen < (alloc)) {\
+ r = alloc;\
+ } \
+ else {\
+ if (newlen < libsheepyPrealloc) {\
+ r = newlen * 2;\
+ }\
+ else {\
+ r = newlen + libsheepyPrealloc;\
+ }\
+ }\
+ r;\
+ funcend
+
// initialize libsheepy (optional, for debug)
typedef void(*initLibsheepyObjectP)(void);
void initLibsheepyF(const char *progPath, initLibsheepyObjectP initF);