v0.24.0 preview

This commit is contained in:
Leonardo Vencovsky committed 2020-06-12 12:34:33 -03:00
1 parent 767fc0d7fd
commit 203516d8cf
7 files changed
+256 -5

No files matched your search

+5 -5
View File
@@ -12,11 +12,11 @@ addons:
- cmake
- python3.8
script:
- sudo ln -s /usr/bin/gcc-6 /usr/local/bin/gcc
- export CC=gcc-7
- sudo ln -s /usr/bin/gcc-9 /usr/local/bin/gcc
- sudo ln -s /usr/bin/python3.8 /usr/local/bin/python
- export CC=gcc-9
- gcc --version
- python3 --version
- python3.8 autogen.py
- make coverage
- python --version
- make
after_success:
- bash <(curl -s https://codecov.io/bash)
+18
View File
@@ -1,5 +1,22 @@
# RELEASE.MAJOR.MINOR
0.24.0
A lot of breaking changes, with the library more modular now
Comeback of PUBLIC and PRIVATE for the CMC sub-library
Callbacks are now optional and can be turned off by defining CMC_NO_CALLBACKS
Added EXT library
New macro CMC_CAMEL_CASE can change the library's style where the default is snake case
Added:
./cor/alloc.h
./cor/callbacks.h
./cor/heap.h
Complete rework of tests and code coverage
Removed cmc_flags, where now every flag is an enum (CMC_FLAGS_OK, CMC_FLAGS_ERROR, etc)
Different include guards
New way to generate code using PARAM
Code now completely changed by using the CMC_ macro to concatenate tokens
Token concatenation with SNAME now uses special macros that allow customization of the suffixes
0.23.1
Added ./cor/bitset.h
Added foreach tests
@@ -8,6 +25,7 @@
0.23.0
Added ./cmc/bitset.h
Added ./cor/flags.h
Added ./utl/futils.h
Added ./utl/mutex.h
Added ./utl/thread.h
+71
View File
@@ -21,6 +21,77 @@
## Table of Contents
* Installation
* Usage
* Contributing
* License
* Features
## Installation
No installation is required. The entire library is made of header files and can be directly included into your project.
## Usage
The header `macro_collections.h` includes every feature from the library and comes with higher level APIs that help you generate collections from specific sub-libraries with specific extensions.
```c
// WIP
#include "macro_collections.h"
// A PARAM is a standard way to pass required parameters to the lower level API.
// It is a tuple of form (PFX, SNAME, SIZE, K, V). In this case, not all of them
// are used, so we can leave them empty.
#define MY_LIST_PARAMS (si32, stacki32, , , int32_t)
// High level API. Generate a LIST from the CMC library with the STR extension
C_MACRO_COLLECTIONS_GEN(PUBLIC, CMC, LIST, MY_LIST_PARAMS, (STR))
bool int_str(FILE *fptr, int val)
{
return 0 <= fprintf(fptr, "%d", val);
}
int main(void)
{
struct stack_int *stack = sint_new(100, &(struct stack_int_fval) { .str = int_str });
si32_free(stack);
}
```
## Contributing
## Features
The C Macro Collections library is organized into many other sub-libraries. The following table is a quick overview.
| Library | Name | Description |
| :-----: | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| CMC | The main C Macro Collections | The main library with variably-sized collections |
| COR | Core | Core functionalities used by more than one collection, usually from different sub-libraries |
| EXT | Extensions | Extension to collections from CMC, SAC and TSC libraries |
| INT | Integrations | Macros that facilitate the creation of code that involves more than one type of collection, e.g. transforming a set to a list |
| SAC | Statically Allocated Collections | Collections with a fixed sized array that don't use any heap allocation |
| TSC | Thread-Safe Collections | Collections that allow multiple operations from multiple threads |
| UTL | Utilities | Utilities for the library |
Every macro that generates code for a certain collection can be found with the following template. Some exceptions exist as certain collections don't have or can't have some features. One big example is the `UTL` library, which does not follow this pattern.
```
macro_name := CMC_[ lib ]_[ collection ]_[ part ]_[ file ]
lib := CMC | COR | DEV | EXT | INT | SAC | TSC
collection := BITSET | DEQUE | HASHBIDIMAP | HASHMAP | HASHMULTIMAP | HASHMULTISET | HASHSET | HEAP | INTERVALHEAP | LINKEDLIST | LIST | QUEUE | SORTEDLIST | STACK | TREEBIDIMAP | TREEMAP | TREEMULTIMAP | TREEMULTISET | TREESET
part := CORE | ITER | INIT | SETF | NODE ...
file := HEADER | SOURCE
```
__Some `collection`s might not be present in a certain `lib`. Check the documentation.__
Every macro is suffixed by `CMC` and each section is separated by an underscore (`_`). The first section is the library (`lib`). The second is the collection name in all uppercase. Then the `part` (or which feature from it) that you wish to generate. And last, if it is code that should belong to a header file or code that should belong to a source file.
* Project Structure
* Available Collections
* Features
@@ -0,0 +1,46 @@
#ifndef COUNT
#error "Please define COUNT"
#endif
#include "cmc/hashmap.h"
CMC_CMC_HASHMAP_CORE(PUBLIC, HEADER, (hmi32, hashmapi32, , int32_t, int32_t))
CMC_CMC_HASHMAP_CORE(PUBLIC, SOURCE, (hmi32, hashmapi32, , int32_t, int32_t))
int cmp(int32_t a, int32_t b)
{
return (a > b) - (a < b);
}
size_t hash(int32_t a)
{
size_t x = (size_t)a;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = (x >> 16) ^ x;
return x;
}
struct hashmapi32_fkey *fkey = &(struct hashmapi32_fkey) {
.cmp = cmp,
.hash = hash,
NULL
};
struct hashmapi32_fval *fval = &(struct hashmapi32_fval) {
.cmp = cmp,
.hash = hash,
NULL
};
int main(void)
{
struct hashmapi32 *map = hmi32_new(COUNT, 0.6, fkey, fval);
for (int32_t i = 0; i < COUNT; i++)
hmi32_insert(map, i, i);
hmi32_free(map);
return 0;
}
@@ -0,0 +1,58 @@
import sys
import time
import subprocess
ITERATIONS = 10
VERBOSE = False
NL = '\n'
INCLUDE = "../../../src"
CC = 'gcc'
CCPP = 'g++' # LoL
OPT = '-O3'
COUNT = 2000000
# Common args
args = ['-I', INCLUDE, OPT, f'-DCOUNT={COUNT}', '-DCMC_NO_CALLBACKS']
c_args = [CC, 'hashmap.c', '-o', 'hashmap.exe']
cpp_args = [CCPP, 'unorderedmap.cpp', '-I', INCLUDE, '-o', 'unorderedmap.exe', OPT, f'-DCOUNT={COUNT}']
c_args.extend(args)
cpp_args.extend(args)
subprocess.check_output(c_args)
subprocess.check_output(cpp_args)
total = 0
for i in range(ITERATIONS):
print(f'{i}...', end='')
sys.stdout.flush()
start_time = time.time()
subprocess.call(['./hashmap.exe'])
delta = time.time() - start_time
total += delta
if VERBOSE:
print(f'({delta})')
avg = int(((total / ITERATIONS) * 1e9) / COUNT)
print(f'{"" if VERBOSE else NL}{total / ITERATIONS} seconds for {COUNT} -> AVG[{avg} ns] [hashmap.exe]{NL if VERBOSE else ""}')
total = 0
for i in range(ITERATIONS):
print(f'{i}...', end='')
sys.stdout.flush()
start_time = time.time()
subprocess.call(['./unorderedmap.exe'])
delta = time.time() - start_time
total += delta
if VERBOSE:
print(f'({delta})')
avg = int(((total / ITERATIONS) * 1e9) / COUNT)
print(f'{"" if VERBOSE else NL}{total / ITERATIONS} seconds for {COUNT} -> AVG[{avg} ns] [unorderedmap.exe]{NL if VERBOSE else ""}')
@@ -0,0 +1,16 @@
#ifndef COUNT
#error "Please define COUNT"
#endif
#include <unordered_map>
#include <cstdint>
int main(void)
{
std::unordered_map<int32_t, int32_t> map(COUNT);
for (int32_t i = 0; i < COUNT; i++)
map.insert({i, i});
return 0;
}
+42
View File
@@ -0,0 +1,42 @@
#include <math.h>
#include "cmc/bitset.h"
CMC_CMC_BITSET_CORE(PUBLIC, HEADER, (bs, bitset))
CMC_CMC_BITSET_CORE(PUBLIC, SOURCE, (bs, bitset))
// All the prime numbers up to 1 billion
// With -O3:
// 28.583 s runtime
// 120 MB RAM
// 490 MB file size
int main(void)
{
const size_t n = 1000000000;
struct bitset *set = bs_new(n);
if (!set)
return 1;
bs_set_range(set, 0, n);
size_t up_to = sqrt((double)n) + 1;
for (size_t i = 2; i < up_to; ++i)
{
if (bs_get(set, i))
{
for (size_t j = 2 * i; j < n; j += i)
bs_clear(set, j);
}
}
FILE *file = fopen("primes.txt", "w");
for (size_t i = 2; i < n; i++)
{
if (bs_get(set, i))
fprintf(file, "%" PRIuMAX " ", i);
}
fclose(file);
}