universe@264: --- universe@264: title: Modules universe@264: --- universe@259: universe@259: UCX provides several modules for data structures and algorithms. universe@259: You may choose to use specific modules by inclueding the corresponding header universe@259: file. universe@259: Please note, that some modules make use of other UCX modules. universe@259: For instance, the [Allocator](#allocator) module is used by many other modules universe@259: to allow flexible memory allocation. universe@259: By default the header files are placed into an `ucx` directory within your universe@259: systems include directory. In this case you can use an module by including it universe@259: via `#include `. universe@259: Required modules are included automatically. universe@259: universe@267:
universe@267: universe@267: ----------------------- ---------------------- ---------------------------- ------------------------- universe@267: [Allocator](#allocator) [AVL Tree](#avl) [Buffer](#buffer) [List](#list) universe@267: [Logging](#logging) [Map](#map) [Memory Pool](#mempool) [Properties](#properties) universe@267: [Stack](#stack) [String](#string) [Testing](#test) [Utilities](#utils) universe@267: ----------------------- ---------------------- ---------------------------- ------------------------- universe@267: universe@267:
universe@267: universe@259: universe@259: universe@259: ## Allocator universe@259: universe@259: *Header file:* [allocator.h](api/allocator_8h.html) universe@259: *Required modules:* None. universe@259: universe@259: A UCX allocator consists of a pointer to the memory area / pool and four universe@259: function pointers to memory management functions operating on this memory universe@259: area / pool. These functions shall behave equivalent to the standard libc universe@259: functions `malloc`, `calloc`, `realloc` and `free`. universe@259: universe@259: The signature of the memory management functions is based on the signature universe@259: of the respective libc function but each of them takes the pointer to the universe@259: memory area / pool as first argument. universe@259: universe@259: As the pointer to the memory area / pool can be arbitrarily chosen, any data universe@259: can be provided to the memory management functions. One example is the universe@259: [UCX Memory Pool](#mempool). universe@259: universe@259: universe@259: universe@259: ## AVL Tree universe@259: universe@259: *Header file:* [avl.h](api/avl_8h.html) universe@259: *Required modules:* [Allocator](#allocator) universe@259: universe@259: This binary search tree implementation allows average O(1) insertion and universe@259: removal of elements (excluding binary search time). universe@259: All common binary tree operations are implemented. Furthermore, this module universe@259: provides search functions via lower and upper bounds. universe@259: universe@259: universe@259: universe@259: ## Buffer universe@259: universe@259: *Header file:* [buffer.h](api/buffer_8h.html) universe@259: *Required modules:* None. universe@259: universe@259: Instances of this buffer implementation can be used to read from or to write to universe@259: memory like you would do with a stream. This allows the use of universe@259: `ucx_stream_copy` from the [Utilities](#utils) module to copy contents from one universe@259: buffer to another or from file or network streams to the buffer and universe@259: vice-versa. universe@259: universe@259: More features for convenient use of the buffer can be enabled, like automatic universe@259: memory management and automatic resizing of the buffer space. universe@259: See the documentation of the macro constants in the header file for more universe@259: information. universe@259: universe@259: universe@259: universe@259: ## List universe@259: universe@259: *Header file:* [list.h](api/list_8h.html) universe@259: *Required modules:* [Allocator](#allocator) universe@259: universe@259: This module provides the data structure and several functions for a doubly universe@259: linked list. Among the common operations like insert, remove, search and sort, universe@259: we allow convenient iteration via a special `UCX_FOREACH` macro. universe@259: universe@259: universe@259: universe@259: ## Logging universe@259: universe@259: *Header file:* [logging.h](api/logging_8h.html) universe@259: *Required modules:* [Map](#map), [String](#string) universe@259: universe@259: The logging module comes with some predefined log levels and allows some more universe@259: customization. You may choose if you want to get timestamps or source file and universe@259: line number logged automatically when outputting a message. universe@259: universe@259: universe@259: universe@259: universe@259: ## Map universe@259: universe@259: *Header file:* [map.h](api/map_8h.html) universe@259: *Required modules:* [Allocator](#allocator), [String](#string) universe@259: universe@259: This module provides a hash map implementation using murmur hash 2 and separate universe@259: chaining with linked lists. Similarly to the list module, we provide a universe@259: `UCX_MAP_FOREACH` macro to conveniently iterate through the key/value pairs. universe@259: universe@259: universe@259: universe@259: ## Memory Pool universe@259: universe@259: *Header file:* [mempool.h](api/mempool_8h.html) universe@259: *Required modules:* [Allocator](#allocator) universe@259: universe@259: Here we have a concrete allocator implementation in the sense of a memory pool. universe@259: This pool allows you to register destructor functions for the allocated memory, universe@259: which are automatically called on the destruction of the pool. universe@259: But you may also register *independent* destructor functions within a pool in universe@259: case, some external library allocated memory for you, which you wish to be universe@259: destroyed together with this pool. universe@259: universe@259: universe@259: universe@259: ## Properties universe@259: universe@259: *Header file:* [properties.h](api/properties_8h.html) universe@259: *Required modules:* [Map](#map) universe@259: universe@259: This module provides load and store function for `*.properties` files. universe@259: The key/value pairs are stored within an UCX Map. universe@259: universe@277: ### Example: Loading properties from a file universe@277: universe@277: ```C universe@277: // Open the file as usual universe@277: FILE* file = fopen("myprops.properties", "r"); universe@277: if (!file) { universe@277: // error handling universe@277: return 1; universe@277: } universe@277: universe@277: // Load the properties from the file universe@277: UcxMap* myprops = ucx_map_new(16); universe@277: if (ucx_properties_load(myprops, file)) { universe@277: // error handling universe@277: fclose(file); universe@277: ucx_map_free(myprops); universe@277: return 1; universe@277: } universe@277: universe@277: // Print out the key/value pairs universe@277: char* propval; universe@277: UcxMapIterator propiter = ucx_map_iterator(myprops); universe@277: UCX_MAP_FOREACH(key, propval, propiter) { universe@277: printf("%s = %s\n", (char*)key.data, propval); universe@277: } universe@277: universe@277: // Don't forget to free the values before freeing the map universe@277: ucx_map_free_content(myprops, NULL); universe@277: ucx_map_free(myprops); universe@277: fclose(file); universe@277: ``` universe@277: universe@259: universe@259: universe@259: ## Stack universe@259: universe@259: *Header file:* [stack.h](api/stack_8h.html) universe@259: *Required modules:* [Allocator](#allocator) universe@259: universe@259: This concrete implementation of an UCX Allocator allows you to grab some amount universe@259: of memory which is then handled as a stack. universe@259: Please note, that the term *stack* only refers to the behavior of this universe@259: allocator. You may still choose if you want to use stack or heap memory universe@259: for the underlying space. universe@259: universe@259: A typical use case is an algorithm where you need to allocate and free large universe@259: amounts of memory very frequently. universe@259: universe@259: universe@259: universe@259: ## String universe@259: universe@259: *Header file:* [string.h](api/string_8h.html) universe@259: *Required modules:* [Allocator](#allocator) universe@259: universe@259: This module provides a safe implementation of bounded string. universe@259: Usually C strings do not carry a length. While for zero-terminated strings you universe@259: can easily get the length with `strlen`, this is not generally possible for universe@259: arbitrary strings. universe@259: The `sstr_t` type of this module always carries the string and its length to universe@259: reduce the risk of buffer overflows dramatically. universe@259: universe@267: ### Initialization universe@267: universe@267: There are several ways to create an `sstr_t`: universe@267: universe@267: ```C universe@267: /* (1) sstr() uses strlen() internally, hence cstr MUST be zero-terminated */ universe@267: sstr_t a = sstr(cstr); universe@267: universe@267: /* (2) cstr does not need to be zero-terminated, if length is specified */ universe@267: sstr_t b = sstrn(cstr, len); universe@267: universe@267: /* (3) S() macro creates sstr_t from a string using sizeof() and using sstrn(). universe@267: This version is especially useful for function arguments */ universe@267: sstr_t c = S("hello"); universe@267: universe@267: /* (4) ST() macro creates sstr_t struct literal using sizeof() */ universe@267: sstr_t d = ST("hello"); universe@267: ``` universe@267: universe@267: You should not use the `S()` or `ST()` macro with string of unknown origin, universe@267: since the `sizeof()` call might not coincide with the string length in those universe@267: cases. If you know what you are doing, it can save you some performance, universe@267: because you do not need the `strlen()` call. universe@267: universe@267: ### Finding the position of a substring universe@267: universe@267: The `sstrstr()` function gives you a new `sstr_t` object starting with the universe@267: requested substring. Thus determining the position comes down to a simple universe@267: subtraction. universe@267: universe@267: ```C universe@267: sstr_t haystack = ST("Here we go!"); universe@267: sstr_t needle = ST("we"); universe@267: sstr_t result = sstrstr(haystack, needle); universe@267: if (result.ptr) universe@267: printf("Found at position %zd.\n", haystack.length-result.length); universe@267: else universe@267: printf("Not found.\n"); universe@267: ``` universe@267: universe@267: ### Spliting a string by a delimiter universe@267: universe@267: The `sstrsplit()` function (and its allocator based version `sstrsplit_a()`) is universe@267: very powerful and might look a bit nasty at a first glance. But it is indeed universe@267: very simple to use. It is even more convenient in combination with a memory universe@267: pool. universe@267: universe@267: ```C universe@267: sstr_t test = ST("here::are::some::strings"); universe@267: sstr_t delim = ST("::"); universe@267: universe@267: ssize_t count = 0; /* no limit */ universe@267: UcxMempool* pool = ucx_mempool_new_default(); universe@267: universe@267: sstr_t* result = sstrsplit_a(pool->allocator, test, delim, &count); universe@267: for (ssize_t i = 0 ; i < count ; i++) { universe@267: /* don't forget to specify the length via the %*s format specifier */ universe@267: printf("%*s\n", result[i].length, result[i].ptr); universe@267: } universe@267: universe@267: ucx_mempool_destroy(pool); universe@267: ``` universe@267: The output is: universe@267: universe@267: here universe@267: are universe@267: some universe@267: strings universe@267: universe@267: The memory pool ensures, that all strings are freed. universe@267: universe@259: universe@259: universe@259: ## Testing universe@259: universe@259: *Header file:* [test.h](api/test_8h.html) universe@259: *Required modules:* None. universe@259: universe@259: This module provides a testing framework which allows you to execute test cases universe@259: within test suites. universe@259: To avoid code duplication within tests, we also provide the possibility to universe@259: define test subroutines. universe@259: universe@259: universe@259: universe@259: ## Utilities universe@259: universe@259: *Header file:* [utils.h](api/utils_8h.html) universe@259: *Required modules:* [Allocator](#allocator), [String](#string) universe@259: universe@259: In this module we provide very general utility function for copy and compare universe@259: operations. universe@259: We also provide several `printf` variants to conveniently print formatted data universe@259: to streams or strings. universe@259: universe@279: ### A simple copy program universe@279: universe@279: The utilities package provides several stream copy functions. universe@279: One of them has a very simple interface and can, for instance, be used to copy universe@279: whole files in a single call. universe@279: This is a minimal working example: universe@279: ```C universe@279: #include universe@279: #include universe@279: universe@279: int main(int argc, char** argv) { universe@279: universe@279: if (argc != 3) { universe@279: fprintf(stderr, "Use %s ", argv[0]); universe@279: return 1; universe@279: } universe@279: universe@279: FILE *srcf = fopen(argv[1], "r"); // insert error handling on your own universe@279: FILE *destf = fopen(argv[2], "w"); universe@279: universe@279: size_t n = ucx_stream_copy(srcf, destf, fread, fwrite); universe@279: printf("%zu bytes copied.\n", n); universe@279: universe@279: fclose(srcf); universe@279: fclose(destf); universe@279: universe@279: universe@279: return 0; universe@279: } universe@279: ``` universe@279: universe@279: