03: optimize hashmap value allocation

This commit is contained in:
0xdeadbeer 2023-11-21 19:00:24 +01:00
parent 5e41f8dd69
commit c005878776
3 changed files with 43 additions and 23 deletions

View File

@ -22,14 +22,23 @@ int find_empty_slot(void **map, int slots) {
return slot; return slot;
} }
int allocate_value(void ***map, int *slots, int bytes) { // If there's Nx fewer used slots than total slots in the map, find the first possible one.
int empty_slot = find_empty_slot(*map, *slots); // 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 (empty_slot == *slots) { if (*used_slots < half_slots) {
(*slots)++; empty_slot = find_empty_slot(*map, *used_slots);
*map = realloc(*map, sizeof(void *)*(*slots)); goto jump;
} }
empty_slot = *total_slots;
(*total_slots)++;
*map = realloc(*map, sizeof(void *)*(*total_slots));
jump:
if (*map == NULL) if (*map == NULL)
return MEMERR; return MEMERR;
@ -37,6 +46,7 @@ int allocate_value(void ***map, int *slots, int bytes) {
if (new_value == NULL) if (new_value == NULL)
return MEMERR; return MEMERR;
(*used_slots)++;
(*map)[empty_slot] = new_value; (*map)[empty_slot] = new_value;
return empty_slot; return empty_slot;

View File

@ -4,6 +4,6 @@
#include "structs.h" #include "structs.h"
int find_empty_slot(void **map, int slots); 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 #endif

View File

@ -11,11 +11,13 @@
#define DEBUG 0x0010 #define DEBUG 0x0010
#define PORT 9080 #define PORT 9080
int objects_count = 0;
struct object **objects_map; struct object **objects_map;
int objects_map_size = 0;
int objects_count = 0;
int connections_count = 0;
struct connection **connections_map; struct connection **connections_map;
int connections_map_size = 0;
int connections_count = 0;
void handle_player_input(struct object *obj, char *message) { void handle_player_input(struct object *obj, char *message) {
uint8_t action = message[0]; uint8_t action = message[0];
@ -26,8 +28,9 @@ void handle_player_input(struct object *obj, char *message) {
if (action & LEFT_MOVEMENT) if (action & LEFT_MOVEMENT)
obj->x -= MOVEMENT_SPEED; obj->x -= MOVEMENT_SPEED;
if (action & JUMP_MOVEMENT) { if (obj->colliding && (action & JUMP_MOVEMENT)) {
obj->force -= MOVEMENT_SPEED; obj->force -= MOVEMENT_SPEED * 3;
obj->y += obj->force;
obj->colliding = 0; obj->colliding = 0;
} }
@ -35,12 +38,14 @@ void handle_player_input(struct object *obj, char *message) {
} }
void handle_player_physics(struct object *obj) { void handle_player_physics(struct object *obj) {
if (obj->y < 200) int touching_ground = obj->y >= 200;
obj->force += GRAVITY;
else { if (touching_ground) {
obj->colliding = 1; obj->force = 0;
obj->y = 200; obj->y = 200;
} obj->colliding = 1;
} else
obj->force += GRAVITY;
obj->y += obj->force; obj->y += obj->force;
} }
@ -48,7 +53,7 @@ void handle_player_physics(struct object *obj) {
int broadcast_event(int format, int object_id) { int broadcast_event(int format, int object_id) {
struct object *obj = objects_map[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]; struct connection *con = connections_map[iter];
if (con == NULL) if (con == NULL)
continue; continue;
@ -120,8 +125,13 @@ int handle_player(void *data) {
SDLNet_FreeSocketSet(set); SDLNet_FreeSocketSet(set);
SDLNet_TCP_Close(connection_data->socket); SDLNet_TCP_Close(connection_data->socket);
objects_map[connection_data->obj_id] = NULL; objects_map[connection_data->obj_id] = NULL;
objects_count--;
connections_map[connection_data->id] = NULL; connections_map[connection_data->id] = NULL;
connections_count--;
free(obj); free(obj);
free(data); free(data);
@ -186,13 +196,13 @@ int main(int argc, char *argv[]) {
fprintf(stdout, "Notice: accepted a connection from client!\n"); 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) { if (new_object_slot == MEMERR) {
fprintf(stderr, "MEMERR: failed allocating memory for new object\n"); fprintf(stderr, "MEMERR: failed allocating memory for new object\n");
return STDERR; 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) { if (new_connection_slot == MEMERR) {
fprintf(stderr, "MEMERR: failed allocating memory for new connection\n"); fprintf(stderr, "MEMERR: failed allocating memory for new connection\n");
return STDERR; return STDERR;