Refactor array (#71)

The array container is now 3% faster.
This commit is contained in:
Bailey Thompson
2020-08-08 19:05:44 -04:00
committed by GitHub
parent 48b0751b6c
commit fdde32d981
4 changed files with 54 additions and 60 deletions

View File

@@ -303,19 +303,19 @@ unordered_multimap unordered_multimap_destroy(unordered_multimap me);
/**
* The array data structure, which is a static contiguous array.
*/
typedef struct internal_array *array;
typedef char *array;
/* Starting */
array array_init(int element_count, size_t data_size);
array array_init(size_t element_count, size_t data_size);
/* Utility */
int array_size(array me);
size_t array_size(array me);
void array_copy_to_array(void *arr, array me);
void *array_get_data(array me);
/* Accessing */
int array_set(array me, int index, void *data);
int array_get(void *data, array me, int index);
int array_set(array me, size_t index, void *data);
int array_get(void *data, array me, size_t index);
/* Ending */
array array_destroy(array me);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019 Bailey Thompson
* Copyright (c) 2017-2020 Bailey Thompson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,14 +24,14 @@
#include <errno.h>
#include "include/array.h"
struct internal_array {
size_t bytes_per_item;
int item_count;
void *data;
};
const size_t book_keeping_size = sizeof(size_t);
const size_t arr_size_offset = 0;
const size_t data_size_offset = sizeof(size_t);
const size_t data_ptr_offset = 2 * sizeof(size_t);
/**
* Initializes an array.
* Initializes an array. If the multiplication of the element count and the
* data size overflows, it is undefined behavior.
*
* @param element_count the number of elements in the array; must not be
* negative
@@ -41,27 +41,19 @@ struct internal_array {
* initialized due to either invalid input arguments or memory
* allocation error
*/
array array_init(const int element_count, const size_t data_size)
array array_init(const size_t element_count, const size_t data_size)
{
struct internal_array *init;
if (element_count < 0 || data_size == 0) {
char *init;
if (data_size == 0) {
return NULL;
}
init = malloc(sizeof(struct internal_array));
init = malloc(data_ptr_offset + element_count * data_size);
if (!init) {
return NULL;
}
init->bytes_per_item = data_size;
init->item_count = element_count;
if (init->item_count == 0) {
init->data = NULL;
return init;
}
init->data = calloc((size_t) element_count, data_size);
if (!init->data) {
free(init);
return NULL;
}
memcpy(init + arr_size_offset, &element_count, book_keeping_size);
memcpy(init + data_size_offset, &data_size, book_keeping_size);
memset(init + data_ptr_offset, 0, element_count * data_size);
return init;
}
@@ -72,9 +64,11 @@ array array_init(const int element_count, const size_t data_size)
*
* @return the size of the array
*/
int array_size(array me)
size_t array_size(array me)
{
return me->item_count;
size_t size;
memcpy(&size, me + arr_size_offset, book_keeping_size);
return size;
}
/**
@@ -90,10 +84,11 @@ int array_size(array me)
*/
void array_copy_to_array(void *const arr, array me)
{
if (me->item_count == 0) {
return;
}
memcpy(arr, me->data, me->item_count * me->bytes_per_item);
size_t element_count;
size_t data_size;
memcpy(&element_count, me + arr_size_offset, book_keeping_size);
memcpy(&data_size, me + data_size_offset, book_keeping_size);
memcpy(arr, me + data_ptr_offset, element_count * data_size);
}
/**
@@ -113,15 +108,12 @@ void array_copy_to_array(void *const arr, array me)
*/
void *array_get_data(array me)
{
return me->data;
}
/*
* Determines if the input is illegal.
*/
static int array_is_illegal_input(array me, const int index)
{
return index < 0 || index >= me->item_count;
size_t element_count;
memcpy(&element_count, me + arr_size_offset, book_keeping_size);
if (element_count == 0) {
return NULL;
}
return me + data_ptr_offset;
}
/**
@@ -138,13 +130,16 @@ static int array_is_illegal_input(array me, const int index)
* @return 0 if no error
* @return -EINVAL if invalid argument
*/
int array_set(array me, const int index, void *const data)
int array_set(array me, const size_t index, void *const data)
{
if (array_is_illegal_input(me, index)) {
size_t element_count;
size_t data_size;
memcpy(&element_count, me + arr_size_offset, book_keeping_size);
if (index >= element_count) {
return -EINVAL;
}
memcpy((char *) me->data + index * me->bytes_per_item, data,
me->bytes_per_item);
memcpy(&data_size, me + data_size_offset, book_keeping_size);
memcpy(me + data_ptr_offset + index * data_size, data, data_size);
return 0;
}
@@ -163,13 +158,16 @@ int array_set(array me, const int index, void *const data)
* @return 0 if no error
* @return -EINVAL if invalid argument
*/
int array_get(void *const data, array me, const int index)
int array_get(void *const data, array me, const size_t index)
{
if (array_is_illegal_input(me, index)) {
size_t element_count;
size_t data_size;
memcpy(&element_count, me + arr_size_offset, book_keeping_size);
if (index >= element_count) {
return -EINVAL;
}
memcpy(data, (char *) me->data + index * me->bytes_per_item,
me->bytes_per_item);
memcpy(&data_size, me + data_size_offset, book_keeping_size);
memcpy(data, me + data_ptr_offset + index * data_size, data_size);
return 0;
}
@@ -183,7 +181,6 @@ int array_get(void *const data, array me, const int index)
*/
array array_destroy(array me)
{
free(me->data);
free(me);
return NULL;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019 Bailey Thompson
* Copyright (c) 2017-2020 Bailey Thompson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -28,19 +28,19 @@
/**
* The array data structure, which is a static contiguous array.
*/
typedef struct internal_array *array;
typedef char *array;
/* Starting */
array array_init(int element_count, size_t data_size);
array array_init(size_t element_count, size_t data_size);
/* Utility */
int array_size(array me);
size_t array_size(array me);
void array_copy_to_array(void *arr, array me);
void *array_get_data(array me);
/* Accessing */
int array_set(array me, int index, void *data);
int array_get(void *data, array me, int index);
int array_set(array me, size_t index, void *data);
int array_get(void *data, array me, size_t index);
/* Ending */
array array_destroy(array me);

View File

@@ -3,7 +3,6 @@
static void test_invalid_init(void)
{
assert(!array_init(-1, sizeof(int)));
assert(!array_init(1, 0));
}
@@ -83,8 +82,6 @@ static void test_init_out_of_memory(void)
{
fail_malloc = 1;
assert(!array_init(10, sizeof(int)));
fail_calloc = 1;
assert(!array_init(10, sizeof(int)));
}
#endif