Derive-C
Loading...
Searching...
No Matches
complex/employees.c

Composing arenas, maps & vectors Demonstrating embedding vectors inside hashmaps, and making efficient use of small indexes for arenas.

Composing arenas, maps & vectors Demonstrating embedding vectors inside hashmaps, and making efficient use of small indexes for arenas.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char const* forename;
char const* surname;
} name;
bool name_eq(const name* name_1, const name* name_2) {
if (!name_1 || !name_2)
return false;
if (!name_1->forename || !name_2->forename)
return false;
if (!name_1->surname || !name_2->surname)
return false;
return strcmp(name_1->forename, name_2->forename) == 0 &&
strcmp(name_1->surname, name_2->surname) == 0;
}
void name_debug(const name* self, dc_debug_fmt fmt, FILE* stream) {
(void)fmt;
fprintf(stream, "name@%p { forename: \"%s\", surname: \"%s\" }", self, self->forename,
self->surname);
}
typedef struct {
int value;
} age;
bool age_eq(age const* age_1, age const* age_2) { return age_1->value == age_2->value; }
size_t age_hash(age const* age) { return age->value; }
void age_debug(age const* self, dc_debug_fmt fmt, FILE* stream) {
(void)fmt;
fprintf(stream, "%d years", self->value);
}
typedef struct {
char const* email;
void employee_debug(employee const* self, dc_debug_fmt fmt, FILE* stream) {
fprintf(stream, "employee@%p {\n", self);
dc_debug_fmt_print(fmt, stream, "name: ");
name_debug(&self->name, fmt, stream);
fprintf(stream, ",\n");
dc_debug_fmt_print(fmt, stream, "email: \"%s\",\n", self->email);
dc_debug_fmt_print(fmt, stream, "age: ");
age_debug(&self->age, fmt, stream);
fprintf(stream, ",\n");
}
#define INDEX_BITS 16
#define VALUE employee
#define VALUE_DEBUG employee_debug
#define NAME employees
#define ITEM employees_index_t
#define ITEM_DEBUG employees_index_t_debug
#define NAME same_age_employees
#define KEY age
#define KEY_EQ age_eq
#define KEY_HASH age_hash
#define KEY_DEBUG age_debug
#define VALUE same_age_employees
#define VALUE_DEBUG same_age_employees_debug
#define NAME employees_by_age
typedef struct {
employees data;
employees_by_age by_age;
return (hr_system){
.data = employees_new_with_capacity_for(1000, stdalloc_get()),
.by_age = employees_by_age_new(stdalloc_get()),
};
}
printf("Adding employee %s %s\n", emp.name.forename, emp.name.surname);
employees_index_t idx = employees_insert(&self->data, emp);
same_age_employees* idxes = employees_by_age_try_write(&self->by_age, emp.age);
if (!idxes) {
idxes =
employees_by_age_insert(&self->by_age, emp.age, same_age_employees_new(stdalloc_get()));
}
same_age_employees_push(idxes, idx);
}
same_age_employees const* idxes = employees_by_age_try_read(&self->by_age, age);
if (!idxes) {
return NULL;
}
if (same_age_employees_size(idxes) == 0) {
return NULL;
}
employees_index_t const* idx =
same_age_employees_read(idxes, same_age_employees_size(idxes) - 1);
return employees_read(&self->data, *idx);
}
void hr_system_debug(hr_system const* self, dc_debug_fmt fmt, FILE* stream) {
fprintf(stream, "hr_system@%p {\n", self);
dc_debug_fmt_print(fmt, stream, "data: ");
employees_debug(&self->data, fmt, stream);
fprintf(stream, ",\n");
dc_debug_fmt_print(fmt, stream, "by_age: ");
employees_by_age_debug(&self->by_age, fmt, stream);
fprintf(stream, ",\n");
}
employees_delete(&self->data);
FOR(employees_by_age, &self->by_age, iter, entry) { same_age_employees_delete(entry.value); }
employees_by_age_delete(&self->by_age);
}
int main() {
employee frank = {
.age = (age){.value = 22},
.email = "veryverylongemail@someprovider.net",
.name =
(name){
.forename = "Frank",
.surname = "Lee",
},
};
name bob_name = {
.forename = "Bob",
.surname = "Mike",
};
employee bob = {
.age = (age){.value = 22},
.email = "bib@cool.org",
.name = bob_name,
};
employee const* newest_22 = hr_system_newest_of_age(&hr, (age){.value = 22});
DC_ASSERT(newest_22);
DC_ASSERT(name_eq(&newest_22->name, &bob_name));
}
static ITEM * data(SELF *self)
Definition template.h:261
void age_debug(age const *self, dc_debug_fmt fmt, FILE *stream)
Definition employees.c:44
employee const * hr_system_newest_of_age(hr_system const *self, age age)
Definition employees.c:116
void employee_debug(employee const *self, dc_debug_fmt fmt, FILE *stream)
Definition employees.c:55
void name_debug(const name *self, dc_debug_fmt fmt, FILE *stream)
Definition employees.c:32
bool age_eq(age const *age_1, age const *age_2)
Definition employees.c:42
bool name_eq(const name *name_1, const name *name_2)
Definition employees.c:20
void hr_system_delete(hr_system *self)
Definition employees.c:145
size_t age_hash(age const *age)
Definition employees.c:43
hr_system hr_system_new()
Definition employees.c:98
void hr_system_new_employee(hr_system *self, employee emp)
Definition employees.c:105
void hr_system_debug(hr_system const *self, dc_debug_fmt fmt, FILE *stream)
Definition employees.c:129
dc_debug_fmt dc_debug_fmt_scope_end(dc_debug_fmt fmt)
Definition fmt.h:39
dc_debug_fmt dc_debug_fmt_scope_begin(dc_debug_fmt fmt)
Definition fmt.h:33
static void dc_debug_fmt_print(dc_debug_fmt fmt, FILE *stream, const char *format,...)
Definition fmt.h:22
static dc_debug_fmt dc_debug_fmt_new()
Definition fmt.h:14
#define FOR(TYPE, INSTANCE, ITER, ITEM)
Definition for.h:9
#define DC_ASSERT(expr,...)
Definition panic.h:36
int main()
Definition staticbump.c:45
int value
Definition employees.c:39
Debug format helpers for debug printin data structures.
Definition fmt.h:10
char const * email
Definition employees.c:51
age age
Definition employees.c:52
name name
Definition employees.c:50
employees data
Definition employees.c:94
employees_by_age by_age
Definition employees.c:95
char const * forename
Definition employees.c:16
char const * surname
Definition employees.c:17
static FILE * stream(SELF *self)
Opens a file for.
Definition template.h:107