docs/Writerside/topics/mempool.h.md

Thu, 23 Jan 2025 01:33:36 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 23 Jan 2025 01:33:36 +0100
branch
docs/3.1
changeset 1141
a06a2d27c043
child 1142
9437530176bc
permissions
-rw-r--r--

create new page structure

relates to #451

1141
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1 # mempool.h
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
2
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
3 A memory pool is providing an allocator implementation that automatically deallocates the memory upon its destruction.
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
4 It also allows you to register destructor functions for the allocated memory, which are automatically called before
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
5 the memory is deallocated.
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
6 Additionally, you may also register _independent_ destructor functions within a pool in case some external library
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
7 allocated memory for you, which should be freed together with this pool.
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
8
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
9 Many UCX features support the use of an allocator.
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
10 The [strings](#string), for instance, provide several functions suffixed with `_a` that allow specifying an allocator.
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
11 You can use this to keep track of the memory occupied by dynamically allocated strings and cleanup everything with
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
12 just a single call to `cxMempoolFree()`.
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
13
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
14 The following code illustrates this on the example of reading a CSV file into memory.
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
15 ```C
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
16 #include <stdio.h>
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
17 #include <cx/mempool.h>
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
18 #include <cx/linked_list.h>
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
19 #include <cx/string.h>
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
20 #include <cx/buffer.h>
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
21 #include <cx/utils.h>
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
22
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
23 typedef struct {
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
24 cxstring column_a;
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
25 cxstring column_b;
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
26 cxstring column_c;
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
27 } CSVData;
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
28
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
29 int main(void) {
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
30 CxMempool* pool = cxBasicMempoolCreate(128);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
31
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
32 FILE *f = fopen("test.csv", "r");
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
33 if (!f) {
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
34 perror("Cannot open file");
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
35 return 1;
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
36 }
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
37 // close the file automatically at pool destruction
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
38 cxMempoolRegister(pool, f, (cx_destructor_func) fclose);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
39
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
40 // create a buffer using the memory pool for destruction
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
41 CxBuffer *content = cxBufferCreate(NULL, 256, pool->allocator, CX_BUFFER_AUTO_EXTEND);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
42
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
43 // read the file into the buffer and turn it into a string
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
44 cx_stream_copy(f, content, (cx_read_func) fread, cxBufferWriteFunc);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
45 fclose(f);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
46 cxstring contentstr = cx_strn(content->space, content->size);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
47
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
48 // split the string into lines - use the mempool for allocating the target array
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
49 cxstring* lines;
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
50 size_t lc = cx_strsplit_a(pool->allocator, contentstr,
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
51 CX_STR("\n"), SIZE_MAX, &lines);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
52
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
53 // skip the header and parse the remaining data into a linked list
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
54 // the nodes of the linked list shall also be allocated by the mempool
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
55 CxList* datalist = cxLinkedListCreate(pool->allocator, NULL, sizeof(CSVData));
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
56 for (size_t i = 1 ; i < lc ; i++) {
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
57 if (lines[i].length == 0) continue;
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
58 cxstring fields[3];
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
59 size_t fc = cx_strsplit(lines[i], CX_STR(";"), 3, fields);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
60 if (fc != 3) {
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
61 fprintf(stderr, "Syntax error in line %zu.\n", i);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
62 cxMempoolFree(pool);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
63 return 1;
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
64 }
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
65 CSVData data;
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
66 data.column_a = fields[0];
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
67 data.column_b = fields[1];
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
68 data.column_c = fields[2];
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
69 cxListAdd(datalist, &data);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
70 }
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
71
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
72 // iterate through the list and output the data
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
73 CxIterator iter = cxListIterator(datalist);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
74 cx_foreach(CSVData*, data, iter) {
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
75 printf("Column A: %.*s | "
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
76 "Column B: %.*s | "
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
77 "Column C: %.*s\n",
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
78 (int)data->column_a.length, data->column_a.ptr,
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
79 (int)data->column_b.length, data->column_b.ptr,
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
80 (int)data->column_c.length, data->column_c.ptr
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
81 );
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
82 }
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
83
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
84 // cleanup everything, no manual free() needed
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
85 cxMempoolFree(pool);
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
86
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
87 return 0;
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
88 }
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
89 ```
a06a2d27c043 create new page structure
Mike Becker <universe@uap-core.de>
parents:
diff changeset
90

mercurial