From c005878776c65a1f6ee8beda82a272eb67b57441 Mon Sep 17 00:00:00 2001 From: 0xdeadbeer <64986162+0xdeadbeer@users.noreply.github.com> Date: Tue, 21 Nov 2023 19:00:24 +0100 Subject: [PATCH] 03: optimize hashmap value allocation --- 03-network/server/src/hashmap.c | 28 ++++++++++++++++--------- 03-network/server/src/hashmap.h | 2 +- 03-network/server/src/main.c | 36 +++++++++++++++++++++------------ 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/03-network/server/src/hashmap.c b/03-network/server/src/hashmap.c index 7c03681..a458183 100644 --- a/03-network/server/src/hashmap.c +++ b/03-network/server/src/hashmap.c @@ -22,21 +22,31 @@ int find_empty_slot(void **map, int slots) { return slot; } -int allocate_value(void ***map, int *slots, int bytes) { - int empty_slot = find_empty_slot(*map, *slots); +// If there's Nx fewer used slots than total slots in the map, find the first possible one. +// Else reallocate the map and use the end slot +// Then allocate an object of size BYTES and add it into the map. +int allocate_value(void ***map, int *total_slots, int *used_slots, int bytes) { + int half_slots = (*total_slots) / 2; + int empty_slot = 0; + + if (*used_slots < half_slots) { + empty_slot = find_empty_slot(*map, *used_slots); + goto jump; + } - if (empty_slot == *slots) { - (*slots)++; - *map = realloc(*map, sizeof(void *)*(*slots)); - } + empty_slot = *total_slots; + (*total_slots)++; + *map = realloc(*map, sizeof(void *)*(*total_slots)); - if (*map == NULL) +jump: + if (*map == NULL) return MEMERR; - void *new_value = calloc(1, bytes); + void *new_value = calloc(1, bytes); if (new_value == NULL) - return MEMERR; + return MEMERR; + (*used_slots)++; (*map)[empty_slot] = new_value; return empty_slot; diff --git a/03-network/server/src/hashmap.h b/03-network/server/src/hashmap.h index 1d97232..5beed26 100644 --- a/03-network/server/src/hashmap.h +++ b/03-network/server/src/hashmap.h @@ -4,6 +4,6 @@ #include "structs.h" int find_empty_slot(void **map, int slots); -int allocate_value(void ***map, int *slots, int bytes); +int allocate_value(void ***map, int *total_slots, int *used_slots, int bytes); #endif diff --git a/03-network/server/src/main.c b/03-network/server/src/main.c index e300282..f13f5a4 100644 --- a/03-network/server/src/main.c +++ b/03-network/server/src/main.c @@ -11,11 +11,13 @@ #define DEBUG 0x0010 #define PORT 9080 -int objects_count = 0; struct object **objects_map; +int objects_map_size = 0; +int objects_count = 0; -int connections_count = 0; struct connection **connections_map; +int connections_map_size = 0; +int connections_count = 0; void handle_player_input(struct object *obj, char *message) { uint8_t action = message[0]; @@ -26,8 +28,9 @@ void handle_player_input(struct object *obj, char *message) { if (action & LEFT_MOVEMENT) obj->x -= MOVEMENT_SPEED; - if (action & JUMP_MOVEMENT) { - obj->force -= MOVEMENT_SPEED; + if (obj->colliding && (action & JUMP_MOVEMENT)) { + obj->force -= MOVEMENT_SPEED * 3; + obj->y += obj->force; obj->colliding = 0; } @@ -35,12 +38,14 @@ void handle_player_input(struct object *obj, char *message) { } void handle_player_physics(struct object *obj) { - if (obj->y < 200) - obj->force += GRAVITY; - else { - obj->colliding = 1; - obj->y = 200; - } + int touching_ground = obj->y >= 200; + + if (touching_ground) { + obj->force = 0; + obj->y = 200; + obj->colliding = 1; + } else + obj->force += GRAVITY; obj->y += obj->force; } @@ -48,7 +53,7 @@ void handle_player_physics(struct object *obj) { int broadcast_event(int format, int object_id) { struct object *obj = objects_map[object_id]; - for (int iter = 0; iter < connections_count; iter++) { + for (int iter = 0; iter < connections_map_size; iter++) { struct connection *con = connections_map[iter]; if (con == NULL) continue; @@ -120,8 +125,13 @@ int handle_player(void *data) { SDLNet_FreeSocketSet(set); SDLNet_TCP_Close(connection_data->socket); + objects_map[connection_data->obj_id] = NULL; + objects_count--; + connections_map[connection_data->id] = NULL; + connections_count--; + free(obj); free(data); @@ -186,13 +196,13 @@ int main(int argc, char *argv[]) { fprintf(stdout, "Notice: accepted a connection from client!\n"); - int new_object_slot = allocate_value((void ***) &objects_map, &objects_count, sizeof(struct object)); + int new_object_slot = allocate_value((void ***) &objects_map, &objects_map_size, &objects_count, sizeof(struct object)); if (new_object_slot == MEMERR) { fprintf(stderr, "MEMERR: failed allocating memory for new object\n"); return STDERR; } - int new_connection_slot = allocate_value((void ***) &connections_map, &connections_count, sizeof(struct connection)); + int new_connection_slot = allocate_value((void ***) &connections_map, &connections_map_size, &connections_count, sizeof(struct connection)); if (new_connection_slot == MEMERR) { fprintf(stderr, "MEMERR: failed allocating memory for new connection\n"); return STDERR;