forked from Telodendria/Telodendria
Move Array documentation to man page.
This commit is contained in:
parent
b5d538f2ce
commit
5ecb810a88
3 changed files with 113 additions and 156 deletions
1
TODO.txt
1
TODO.txt
|
@ -96,3 +96,4 @@ Documentation
|
||||||
[x] Convert documentation to man pages
|
[x] Convert documentation to man pages
|
||||||
[x] Clean up dark mode in man page CSS (links)
|
[x] Clean up dark mode in man page CSS (links)
|
||||||
[x] Synopsis table should not be styled
|
[x] Synopsis table should not be styled
|
||||||
|
[ ] Internal API docs
|
||||||
|
|
112
docs/Array.3
Normal file
112
docs/Array.3
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
.Dd $Mdocdate: September 25 2022 $
|
||||||
|
.Dt ARRAY 3
|
||||||
|
.Os Telodendria Project
|
||||||
|
.Sh NAME
|
||||||
|
.Nm Array
|
||||||
|
.Nd A simple dynamic array data structure.
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In Array.h
|
||||||
|
.Ft Array *
|
||||||
|
.Fn ArrayCreate "void"
|
||||||
|
.Ft void
|
||||||
|
.Fn ArrayFree "Array *"
|
||||||
|
.Ft int
|
||||||
|
.Fn ArrayTrim "Array *"
|
||||||
|
.Ft size_t
|
||||||
|
.Fn ArraySize "Array *"
|
||||||
|
.Ft void *
|
||||||
|
.Fn ArrayGet "Array *" "size_t"
|
||||||
|
.Ft int
|
||||||
|
.Fn ArrayInsert "Array *" "void *" "size_t"
|
||||||
|
.Ft int
|
||||||
|
.Fn ArrayAdd "Array *" "void *"
|
||||||
|
.Ft void *
|
||||||
|
.Fn ArrayDelete "Array *" "size_t"
|
||||||
|
.Ft void
|
||||||
|
.Fn ArraySort "Array *" "int (*) (void *, void *)"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
These functions implement a simple array data structure that
|
||||||
|
is automatically resized as necessary when new values are added.
|
||||||
|
This implementation does not actually store the values of the
|
||||||
|
items in it; it only stores pointers to the data. As such, you will
|
||||||
|
still have to manually maintain all your data. The advantage of this
|
||||||
|
is that these functions don't have to copy data, and thus don't care
|
||||||
|
how big the data is. Furthermore, arbitrary data can be stored in the
|
||||||
|
array.
|
||||||
|
.Pp
|
||||||
|
This array implementation is optimized for storage space and appending.
|
||||||
|
Deletions are expensive in that all the items of the list above a deletion
|
||||||
|
are moved down to fill the hole where the deletion occurred. Insertions are
|
||||||
|
also expensive in that all the elements above the given index must be shifted
|
||||||
|
up to make room for the new element.
|
||||||
|
.Pp
|
||||||
|
Due to these design choices, this array implementation is best suited to
|
||||||
|
linear writing, and then linear or random reading.
|
||||||
|
.Pp
|
||||||
|
These functions operate on an array structure which is opaque to the
|
||||||
|
caller.
|
||||||
|
.Pp
|
||||||
|
.Fn ArrayCreate
|
||||||
|
and
|
||||||
|
.Fn ArrayFree
|
||||||
|
allocate and deallocate an array, respectively.
|
||||||
|
Note that
|
||||||
|
.Fn ArrayFree
|
||||||
|
does not free any of the values stored in the array; it is the caller's
|
||||||
|
job to manage the memory for each item. Typically, the caller would
|
||||||
|
iterate over all the items in the array and free them before freeing
|
||||||
|
the array.
|
||||||
|
.Fn ArrayTrim
|
||||||
|
reduces the amount of unused memory by calling
|
||||||
|
.Xr realloc 3
|
||||||
|
on the internal structure to perfectly fit the elements in the array. It
|
||||||
|
is intended to be used by functions that return relatively read-only arrays
|
||||||
|
that will be long-lived.
|
||||||
|
.Pp
|
||||||
|
.Fn ArrayInsert
|
||||||
|
and
|
||||||
|
.Fn ArrayDelete
|
||||||
|
are the main functions used to modify the array.
|
||||||
|
.Fn ArrayAdd
|
||||||
|
is a convenience method that simply appends a value to the end of the
|
||||||
|
array. It uses
|
||||||
|
.Fn ArrayInsert .
|
||||||
|
The array can also be sorted by using
|
||||||
|
.Fn ArraySort ,
|
||||||
|
which takes a pointer to a function that compares elements. The function
|
||||||
|
should take two
|
||||||
|
.Dv void
|
||||||
|
pointers as parameters, and return an integer. The return value indicates
|
||||||
|
to the algorithm how the elements relate to each other. A return value of
|
||||||
|
0 indicates the elements are identical. A return value greater than 0
|
||||||
|
indicates that the first item is "bigger" than the second item and should
|
||||||
|
thus appear after it in the array, and a value less than zero indicates
|
||||||
|
the opposite: the second element should appear after the first in the array.
|
||||||
|
.Pp
|
||||||
|
.Fn ArrayGet
|
||||||
|
is used to get the element at the specified index.
|
||||||
|
.Sh RETURN VALUES
|
||||||
|
.Fn ArrayCreate
|
||||||
|
returns a pointer on the heap to a newly allocated array structure.
|
||||||
|
.Pp
|
||||||
|
.Fn ArrayGet
|
||||||
|
and
|
||||||
|
.Fn ArrayDelete
|
||||||
|
return pointers to values that were put into the array, or
|
||||||
|
.Dv NULL
|
||||||
|
if the provided array is
|
||||||
|
.Dv NULL
|
||||||
|
or the provided index was out of bounds.
|
||||||
|
.Fn ArrayDelete
|
||||||
|
returns the element at the specified index after removing it so that
|
||||||
|
it can be properly handled by the caller.
|
||||||
|
.Pp
|
||||||
|
.Fn ArrayTrim ,
|
||||||
|
.Fn ArrayInsert ,
|
||||||
|
and
|
||||||
|
.Fn ArrayAdd
|
||||||
|
return a boolean value indicating their status. They return a value of zero
|
||||||
|
on failure, and a non-zero value on success.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr HashMap 3 ,
|
||||||
|
.Xr Queue 3
|
|
@ -22,24 +22,6 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Array.h: A simple array data structure that is automatically
|
|
||||||
* resized when new values are added. This implementation does not
|
|
||||||
* actually store the values of the items it; it only stores pointers
|
|
||||||
* to the data. As such, you will still have to manually maintain all
|
|
||||||
* your data. The advantage of this is that this array implementation
|
|
||||||
* doesn't have to copy items, and thus doesn't have to know how big
|
|
||||||
* they are.
|
|
||||||
*
|
|
||||||
* This array is optimized for storage space and appending. Deletions
|
|
||||||
* are expensive in that all the items of the list are moved down
|
|
||||||
* to fill the hole where the deletion occurred. Insertions are
|
|
||||||
* also expensive in that all the elements are shifted to make room
|
|
||||||
* for the new element.
|
|
||||||
*
|
|
||||||
* Due to these, this array implementation is really intended to be
|
|
||||||
* used primarily for linear writing and linear or random reading.
|
|
||||||
*/
|
|
||||||
#ifndef TELODENDRIA_ARRAY_H
|
#ifndef TELODENDRIA_ARRAY_H
|
||||||
#define TELODENDRIA_ARRAY_H
|
#define TELODENDRIA_ARRAY_H
|
||||||
|
|
||||||
|
@ -47,168 +29,30 @@
|
||||||
|
|
||||||
typedef struct Array Array;
|
typedef struct Array Array;
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a new, empty array on the heap.
|
|
||||||
*
|
|
||||||
* Return: A pointer to an Array, or NULL if there was an error
|
|
||||||
* allocating memory for the Array.
|
|
||||||
*/
|
|
||||||
extern Array *
|
extern Array *
|
||||||
ArrayCreate(void);
|
ArrayCreate(void);
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the size of the provided array. Note that this is the number
|
|
||||||
* of elements in the array, not how much memory has been allocated
|
|
||||||
* for it.
|
|
||||||
*
|
|
||||||
* This is an extremely cheap operation, because the size does not
|
|
||||||
* need to be computed; rather it is just pulled right out of the
|
|
||||||
* Array and returned to the caller.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
*
|
|
||||||
* (Array *) The array to check the size of.
|
|
||||||
*
|
|
||||||
* Return: The number of elements in the provided array, or 0 if the
|
|
||||||
* provided array is NULL.
|
|
||||||
*/
|
|
||||||
extern size_t
|
extern size_t
|
||||||
ArraySize(Array *);
|
ArraySize(Array *);
|
||||||
|
|
||||||
/*
|
|
||||||
* Get an element out of the provided array at the provided index.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
*
|
|
||||||
* (Array *) The array to get an element from.
|
|
||||||
* (size_t) The index of the array where the desired element is
|
|
||||||
* located.
|
|
||||||
*
|
|
||||||
* Return: A pointer to the data located at the given index, or NULL
|
|
||||||
* if no array was provided, or the index is greater than or equal
|
|
||||||
* to the size of the array.
|
|
||||||
*/
|
|
||||||
extern void *
|
extern void *
|
||||||
ArrayGet(Array *, size_t);
|
ArrayGet(Array *, size_t);
|
||||||
|
|
||||||
/*
|
|
||||||
* Insert an element into the array at the given index.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
*
|
|
||||||
* (Array *) The array to get the element from.
|
|
||||||
* (void *) The value to insert into the array.
|
|
||||||
* (size_t) The index at which the given value.
|
|
||||||
*
|
|
||||||
* Return: A boolean value that indicates whether or not the insert
|
|
||||||
* was successful. A return value of 0 indicates that the insert was
|
|
||||||
* NOT successful, and a return value of anything else indicates that
|
|
||||||
* the insert was successful.
|
|
||||||
*/
|
|
||||||
extern int
|
extern int
|
||||||
ArrayInsert(Array *, void *, size_t);
|
ArrayInsert(Array *, void *, size_t);
|
||||||
|
|
||||||
/*
|
|
||||||
* Append an element to the end of the array. This function actually
|
|
||||||
* uses ArrayInsert() under the hood, but it makes appending to an
|
|
||||||
* array more convenient because you don't necessarily have to keep
|
|
||||||
* track of the array's size.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
*
|
|
||||||
* (Array *) The array to append to.
|
|
||||||
* (void *) The value to append to the array.
|
|
||||||
*
|
|
||||||
* Return: The result of appending the element, which is the same as
|
|
||||||
* a call to ArrayInsert().
|
|
||||||
*/
|
|
||||||
extern int
|
extern int
|
||||||
ArrayAdd(Array *, void *);
|
ArrayAdd(Array *, void *);
|
||||||
|
|
||||||
/*
|
|
||||||
* Delete an element from an array by shifting all the elements that
|
|
||||||
* come after it down one index.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
*
|
|
||||||
* (Array *) The array to delete a value from.
|
|
||||||
* (size_t) The desired index to delete. All elements above this
|
|
||||||
* index are then shifted down to fill the gap.
|
|
||||||
*
|
|
||||||
* Return: A pointer to the deleted element, so that it can be freed
|
|
||||||
* or otherwise dealt with, or NULL if the array is NULL or the index
|
|
||||||
* is out of bounds.
|
|
||||||
*/
|
|
||||||
extern void *
|
extern void *
|
||||||
ArrayDelete(Array *, size_t);
|
ArrayDelete(Array *, size_t);
|
||||||
|
|
||||||
/*
|
|
||||||
* Sort the array using a simple quick-sort algorithm. This function
|
|
||||||
* works by taking a caller-specified compare function, so that no
|
|
||||||
* assumptions about the data stored in the array need to be made by
|
|
||||||
* this code.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
*
|
|
||||||
* (Array *) The array to sort. Note that the sort will be done
|
|
||||||
* in-place.
|
|
||||||
* (int (*)(void *, void *)) A function that takes in two void
|
|
||||||
* pointers and returns an integer. This function is
|
|
||||||
* responsible for comparing the passed items, and
|
|
||||||
* returning a code that indicates how they should be
|
|
||||||
* ordered. A return value of 0 indicates that the two
|
|
||||||
* items are identical. A return value greater than 0
|
|
||||||
* indicates that the first item is "bigger" than the
|
|
||||||
* second item and should thus appear after it in the
|
|
||||||
* array, and a return value less than zero indicates
|
|
||||||
* the opposite: that the second element should appear
|
|
||||||
* after the first in the array.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
extern void
|
extern void
|
||||||
ArraySort(Array *, int (*) (void *, void *));
|
ArraySort(Array *, int (*) (void *, void *));
|
||||||
|
|
||||||
/*
|
|
||||||
* Free all the memory associated with the given array. Note that this
|
|
||||||
* does not free any of the values themselves; you should explicitly
|
|
||||||
* iterate over the array and free all the values stored inside it
|
|
||||||
* before calling this function, otherwise you may lose all the
|
|
||||||
* pointers the array contains, and thus have a memory leak.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
*
|
|
||||||
* (Array *) The array to free.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
extern void
|
extern void
|
||||||
ArrayFree(Array *);
|
ArrayFree(Array *);
|
||||||
|
|
||||||
/*
|
|
||||||
* "Trim" the array by reallocating it with only the memory it needs
|
|
||||||
* to hold the items it currently has. This function might be beneficial
|
|
||||||
* to call on long-lived arrays that will be read-only, because it
|
|
||||||
* frees any memory on the end of the array that isn't being used. The
|
|
||||||
* array resizing algorithm will most likely allocate too much memory
|
|
||||||
* for most arrays as elements are added, because there's no way to
|
|
||||||
* know exactly how many elements will be stored.
|
|
||||||
*
|
|
||||||
* For example, a library that generates an Array to return to the
|
|
||||||
* user may wish to call this function on it right before returning to
|
|
||||||
* the caller if it is not expected that the caller will be modifying
|
|
||||||
* the array and may hang on to it for a long time.
|
|
||||||
*
|
|
||||||
* Params:
|
|
||||||
*
|
|
||||||
* (Array *) The array to trim extra memory (if any) off the end.
|
|
||||||
* Note that the array will still be fully-functional; if
|
|
||||||
* you add more elements, then more memory will be
|
|
||||||
* allocated like normal.
|
|
||||||
*
|
|
||||||
* Return: Whether or not the trim was successful. The trim may fail if
|
|
||||||
* realloc() fails, or NULL was passed for the array. If realloc()
|
|
||||||
* fails, this function is careful not to clobber the array. Upon
|
|
||||||
* failure of this function, the array is guaranteed to be unaltered.
|
|
||||||
*/
|
|
||||||
extern int
|
extern int
|
||||||
ArrayTrim(Array *);
|
ArrayTrim(Array *);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue