Sat, 01 Jul 2023 14:05:52 +0200
add mempool example
docs/src/features.md | file | annotate | diff | comparison | revisions |
1.1 --- a/docs/src/features.md Wed Jun 28 20:36:25 2023 +0200 1.2 +++ b/docs/src/features.md Sat Jul 01 14:05:52 2023 +0200 1.3 @@ -91,6 +91,93 @@ 1.4 1.5 *Header file:* [mempool.h](api/mempool_8h.html) 1.6 1.7 +A memory pool is providing an allocator implementation that automatically deallocates the memory upon its destruction. 1.8 +It also allows you to register destructor functions for the allocated memory, which are automatically called before 1.9 +the memory is deallocated. 1.10 +Additionally, you may also register _independent_ destructor functions within a pool in case some external library 1.11 +allocated memory for you, which should be destroyed together with this pool. 1.12 + 1.13 +Many UCX features support the use of an allocator. 1.14 +The [strings](#string), for instance, provide several functions suffixed with `_a` that allow specifying an allocator. 1.15 +You can use this to keep track of the memory occupied by dynamically allocated strings and cleanup everything with 1.16 +just a single call to `cxMempoolDestroy()`. 1.17 + 1.18 +The following code illustrates this on the example of reading a CSV file into memory. 1.19 +```C 1.20 +#include <stdio.h> 1.21 +#include <cx/mempool.h> 1.22 +#include <cx/linked_list.h> 1.23 +#include <cx/string.h> 1.24 +#include <cx/buffer.h> 1.25 +#include <cx/utils.h> 1.26 + 1.27 +typedef struct { 1.28 + cxstring column_a; 1.29 + cxstring column_b; 1.30 + cxstring column_c; 1.31 +} CSVData; 1.32 + 1.33 +int main(void) { 1.34 + CxMempool* pool = cxBasicMempoolCreate(128); 1.35 + 1.36 + FILE *f = fopen("test.csv", "r"); 1.37 + if (!f) { 1.38 + perror("Cannot open file"); 1.39 + return 1; 1.40 + } 1.41 + // close the file automatically at pool destruction 1.42 + cxMempoolRegister(pool, f, (cx_destructor_func) fclose); 1.43 + 1.44 + // create a buffer using the memory pool for destruction 1.45 + CxBuffer *content = cxBufferCreate(NULL, 256, pool->allocator, CX_BUFFER_AUTO_EXTEND); 1.46 + 1.47 + // read the file into the buffer and turn it into a string 1.48 + cx_stream_copy(f, content, (cx_read_func) fread, (cx_write_func) cxBufferWrite); 1.49 + cxstring contentstr = cx_strn(content->space, content->size); 1.50 + 1.51 + // split the string into lines - use the mempool for allocating the target array 1.52 + cxstring* lines; 1.53 + size_t lc = cx_strsplit_a(pool->allocator, contentstr, 1.54 + CX_STR("\n"), SIZE_MAX, &lines); 1.55 + 1.56 + // skip the header and parse the remaining data into a linked list 1.57 + // the nodes of the linked list shall also be allocated by the mempool 1.58 + CxList* datalist = cxLinkedListCreate(pool->allocator, NULL, sizeof(CSVData)); 1.59 + for (size_t i = 1 ; i < lc ; i++) { 1.60 + if (lines[i].length == 0) continue; 1.61 + cxstring fields[3]; 1.62 + size_t fc = cx_strsplit(lines[i], CX_STR(";"), 3, fields); 1.63 + if (fc != 3) { 1.64 + fprintf(stderr, "Syntax error in line %zu.\n", i); 1.65 + cxMempoolDestroy(pool); 1.66 + return 1; 1.67 + } 1.68 + CSVData* data = cxMalloc(pool->allocator, sizeof(CSVData)); 1.69 + data->column_a = fields[0]; 1.70 + data->column_b = fields[1]; 1.71 + data->column_c = fields[2]; 1.72 + cxListAdd(datalist, data); 1.73 + } 1.74 + 1.75 + // iterate through the list and output the data 1.76 + CxIterator iter = cxListIterator(datalist); 1.77 + cx_foreach(CSVData*, data, iter) { 1.78 + printf("Column A: %.*s | " 1.79 + "Column B: %.*s | " 1.80 + "Column C: %.*s\n", 1.81 + (int)data->column_a.length, data->column_a.ptr, 1.82 + (int)data->column_b.length, data->column_b.ptr, 1.83 + (int)data->column_c.length, data->column_c.ptr 1.84 + ); 1.85 + } 1.86 + 1.87 + // cleanup everything, no manual free() needed 1.88 + cxMempoolDestroy(pool); 1.89 + 1.90 + return 0; 1.91 +} 1.92 +``` 1.93 + 1.94 ## Iterator 1.95 1.96 *Header file:* [iterator.h](api/iterator_8h.html)