Skip to content

Commit

Permalink
big refactoring on memory allocation
Browse files Browse the repository at this point in the history
  • Loading branch information
brunoczim committed Nov 12, 2020
1 parent c54a752 commit 336b47d
Show file tree
Hide file tree
Showing 22 changed files with 141 additions and 59 deletions.
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ TEST_TAGS_TABLE_OBJS = $(OBJ_DIR)/error.o \
$(OBJ_DIR)/tags/movies.o \
$(OBJ_DIR)/tags.o \
$(OBJ_DIR)/test/tags_table.o
TARGETS = moviedb \
test/prime \
test/csv \
test/trie \
test/movies_table \
test/users_table \
test/tags_table

moviedb: $(MOVIEDB_OBJS)
mkdir -p $(dir $(BUILD_DIR)/$@)
Expand All @@ -158,6 +165,8 @@ $(OBJ_DIR)/%.o: src/%.c $(HEADERS)
mkdir -p $(dir $@)
$(CC) -c $< $(CFLAGS) -o $@

all: $(TARGETS)

test/prime: $(TEST_PRIME_OBJS)
mkdir -p $(dir $(BUILD_DIR)/$@)
$(CC) $(LDFLAGS) $^ -o $(BUILD_DIR)/$@
Expand Down
48 changes: 44 additions & 4 deletions src/alloc.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,50 @@
#include "alloc.h"

extern inline void *moviedb_alloc(size_t bytes, struct error *restrict error);
void *moviedb_alloc(
size_t elem_size,
size_t elements,
struct error *restrict error)
{
size_t size = elem_size * elements;
bool fail = true;
void *mem = NULL;

extern inline void *moviedb_realloc(
if (elem_size == 0 || size / elem_size == elements) {
mem = malloc(size);
fail = mem == NULL && size != 0;
}

if (fail) {
error_set_code(error, error_alloc);
error->data.alloc.elem_size = elem_size;
error->data.alloc.elements = elements;
}

return mem;
}

void *moviedb_realloc(
void *mem,
size_t bytes,
struct error *restrict error);
size_t elem_size,
size_t elements,
struct error *restrict error)
{
size_t size = elem_size * elements;
bool fail = true;
void *new_mem = NULL;

if (elem_size == 0 || size / elem_size == elements) {
new_mem = realloc(mem, size);
fail = new_mem == NULL && size != 0;
}

if (fail) {
error_set_code(error, error_alloc);
error->data.alloc.elem_size = elem_size;
error->data.alloc.elements = elements;
}

return new_mem;
}

extern inline void moviedb_free(void *mem);
28 changes: 8 additions & 20 deletions src/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,10 @@
*
* NULL might still be returned in case of a zero-sized allocation.
*/
inline void *moviedb_alloc(size_t size, struct error *restrict error)
{
void *mem = malloc(size);
if (mem == NULL && size != 0) {
error_set_code(error, error_alloc);
error->data.alloc.size = size;
}
return mem;
}
void *moviedb_alloc(
size_t elem_size,
size_t elements,
struct error *restrict error);

/**
* Reallocates a memory region of size given by size, and a previous
Expand All @@ -33,18 +28,11 @@ inline void *moviedb_alloc(size_t size, struct error *restrict error)
*
* NULL might still be returned in case of a zero-sized allocation.
*/
inline void *moviedb_realloc(
void *moviedb_realloc(
void *mem,
size_t size,
struct error *restrict error)
{
void *new_mem = realloc(mem, size);
if (new_mem == NULL && size != 0) {
error_set_code(error, error_alloc);
error->data.alloc.size = size;
}
return new_mem;
}
size_t elem_size,
size_t elements,
struct error *restrict error);

/**
* Frees memory allocated by moviedb_alloc and moviedb_realloc.
Expand Down
6 changes: 5 additions & 1 deletion src/csv.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ double csv_parse_double(

/* If we are not at the end of the string, the parse failed. */
if (*end != 0) {
error_string = moviedb_alloc(strlen(string) + 1, error);
error_string = moviedb_alloc(
sizeof(*error_string),
strlen(string) + 1,
error);

if (error->code == error_none) {
strcpy(error_string, string);
error_set_code(error, error_double);
Expand Down
4 changes: 3 additions & 1 deletion src/csv/movie.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,14 @@ bool movie_row_parse(
row_out->title = strbuf_copy_cstr(buf, error);
} else if (column == parser->genres_column) {
/* Copies the genres. */
row_out->genres= strbuf_copy_cstr(buf, error);
row_out->genres = strbuf_copy_cstr(buf, error);
}
}
column++;
}

row_boundary = csv_is_row_boundary(&parser->csv_parser);

/* We must end the row with a row boundary (duh). */
if (error->code == error_none && !row_boundary) {
error_set_code(error, error_movie);
Expand Down
2 changes: 2 additions & 0 deletions src/csv/rating.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ bool rating_row_parse(
column++;
}

row_boundary = csv_is_row_boundary(&parser->csv_parser);

/* We must end the row with a row boundary (duh). */
if (error->code == error_none && !row_boundary) {
error_set_code(error, error_movie);
Expand Down
2 changes: 2 additions & 0 deletions src/csv/tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ bool tag_row_parse(
column++;
}

row_boundary = csv_is_row_boundary(&parser->csv_parser);

/* We must end the row with a row boundary (duh). */
if (error->code == error_none && !row_boundary) {
error_set_code(error, error_movie);
Expand Down
2 changes: 1 addition & 1 deletion src/database.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void database_load(

if (error->code == error_none) {
/* Allocates the buffer for file buffering. */
file_buf = moviedb_alloc(IO_BUF_SIZE, error);
file_buf = moviedb_alloc(sizeof(*file_buf), IO_BUF_SIZE, error);
}

/* Actually loads everything, if no error. */
Expand Down
6 changes: 4 additions & 2 deletions src/error.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ void error_print(struct error const *restrict error)

case error_alloc:
fprintf(stderr,
"out of memory, allocation size %zu\n",
error->data.alloc.size);
"%s, requested element size %zu and %zu elements\n",
"out of memory",
error->data.alloc.elem_size,
error->data.alloc.elements);
break;

case error_io:
Expand Down
8 changes: 6 additions & 2 deletions src/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,13 @@ struct csv_error {
*/
struct alloc_error {
/**
* How much was attempted to allocate, in bytes.
* Size of an element in bytes.
*/
size_t size;
size_t elem_size;
/**
* How many elements were allocated.
*/
size_t elements;
};

/**
Expand Down
6 changes: 5 additions & 1 deletion src/id.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ moviedb_id_t moviedb_id_parse(
i++;
} else {
if (error->code == error_none) {
error_string = moviedb_alloc(strlen(string) + 1, error);
error_string = moviedb_alloc(
sizeof(*error_string),
strlen(string) + 1,
error);

if (error->code == error_none) {
/* Copies the input string to an error. */
strcpy(error_string, string);
Expand Down
8 changes: 5 additions & 3 deletions src/movies.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ void movies_init(
table->length = 0;
table->capacity = next_prime(initial_capacity);
table->entries = moviedb_alloc(
sizeof(struct movie **) * table->capacity,
sizeof(*table->entries),
table->capacity,
error);

if (error->code == error_none) {
Expand Down Expand Up @@ -126,7 +127,7 @@ void movies_insert(
index = probe_index(table, movie_row->id, hash);
if (table->entries[index] == NULL) {
/* Allocates a movie to be inserted. */
movie = moviedb_alloc(sizeof(struct movie), error);
movie = moviedb_alloc(sizeof(*movie), 1, error);
} else {
/* Duplicated movie ID error. */
error_set_code(error, error_dup_movie_id);
Expand Down Expand Up @@ -254,7 +255,8 @@ static void resize(
new_table.capacity = next_prime(table->capacity * 2);

new_table.entries = moviedb_alloc(
sizeof(struct movie **) * new_table.capacity,
sizeof(*new_table.entries),
new_table.capacity,
error);

if (error->code == error_none) {
Expand Down
3 changes: 2 additions & 1 deletion src/query/movie.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ static void buf_append(
}
new_rows = moviedb_realloc(
buf->rows,
new_cap * sizeof (struct movie const *),
sizeof(*new_rows),
new_cap,
error);

if (error->code == error_none) {
Expand Down
10 changes: 7 additions & 3 deletions src/query/tags.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ void tags_query_input_init(
struct error *restrict error)
{
query_input->tags = moviedb_alloc(
sizeof(struct tag const *) * capacity,
sizeof(*query_input->tags),
capacity,
error);

query_input->capacity = capacity;
query_input->length = 0;
}
Expand All @@ -57,7 +59,8 @@ void tags_query_input_add(

new_tags = moviedb_realloc(
query_input->tags,
sizeof(struct tag const *) * new_cap,
sizeof(*new_tags),
new_cap,
error);

if (error->code == error_none) {
Expand Down Expand Up @@ -176,7 +179,8 @@ static void buf_append(

new_movies = moviedb_realloc(
buf->rows,
sizeof(struct movie const *) * new_cap,
sizeof(*new_movies),
new_cap,
error);

if (error->code == error_none) {
Expand Down
3 changes: 2 additions & 1 deletion src/query/topn.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ void topn_query_init(
buf->capacity = capacity;
buf->length = 0;
buf->rows = moviedb_alloc(
sizeof(struct movie const *) * buf->capacity,
sizeof(*buf->rows),
buf->capacity,
error);
}

Expand Down
12 changes: 8 additions & 4 deletions src/strbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ void strbuf_reserve(

/* Tries to reallocate. */
new_capacity = buf->capacity + additional;
new_alloc = moviedb_realloc(buf->ptr, new_capacity, error);
new_alloc = moviedb_realloc(
buf->ptr,
sizeof(*buf->ptr),
new_capacity,
error);

if (error->code == error_none) {
/* If no error happened, publish the new allocation. */
Expand All @@ -42,7 +46,7 @@ char *strbuf_copy_cstr(

if (buf->length == 0) {
/* Empty string buffer. */
cstr = moviedb_alloc(1, error);
cstr = moviedb_alloc(sizeof(*cstr), 1, error);
if (error->code == error_none) {
*cstr = 0;
}
Expand All @@ -54,7 +58,7 @@ char *strbuf_copy_cstr(
strbuf_init(buf);
} else {
/* With extra space. So, it makes a new allocation. */
cstr = moviedb_alloc(buf->length, error);
cstr = moviedb_alloc(sizeof(*cstr), buf->length, error);
if (error->code == error_none) {
memcpy(cstr, buf->ptr, buf->length);
}
Expand All @@ -72,7 +76,7 @@ char *strbuf_copy_cstr(
* Last string buffer character is not \0 AND adding \0 would NOT make
* the buffer to be at full capacity. It would be either below or above.
*/
cstr = moviedb_alloc(buf->length + 1, error);
cstr = moviedb_alloc(sizeof(*cstr), buf->length + 1, error);
if (error->code == error_none) {
memcpy(cstr, buf->ptr, buf->length);
cstr[buf->length] = 0;
Expand Down
8 changes: 5 additions & 3 deletions src/tags.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ void tags_init(
table->length = 0;
table->capacity = next_prime(initial_capacity);
table->entries = moviedb_alloc(
sizeof(struct tag **) * table->capacity,
sizeof(*table->entries),
table->capacity,
error);

if (error->code == error_none) {
Expand Down Expand Up @@ -119,7 +120,7 @@ static struct tag *tag_init(
struct tag_csv_row *restrict tag_row,
struct error *restrict error)
{
struct tag *tag = moviedb_alloc(sizeof(struct tag), error);
struct tag *tag = moviedb_alloc(sizeof(*tag), 1, error);

if (error->code == error_none) {
/* Initializes the tag. */
Expand Down Expand Up @@ -180,7 +181,8 @@ static void resize(
new_table.capacity = next_prime(table->capacity * 2);

new_table.entries = moviedb_alloc(
sizeof(struct tag **) * new_table.capacity,
sizeof(*new_table.entries),
new_table.capacity,
error);

if (error->code == error_none) {
Expand Down
Loading

0 comments on commit 336b47d

Please sign in to comment.