fix hashmap
This commit is contained in:
@@ -14,19 +14,46 @@ struct hashmap {
|
||||
struct hashmap *next;
|
||||
};
|
||||
|
||||
/* Calculate the hash code of a file descriptor */
|
||||
/**
|
||||
* @brief Calculates the hash code of a given file descriptor
|
||||
*
|
||||
* @param sockfd[in] The file descriptor
|
||||
* @return int Returns the hash code
|
||||
*/
|
||||
int hash(int sockfd);
|
||||
|
||||
/* Initialize the hash map */
|
||||
/**
|
||||
* @brief Initializes the hash map
|
||||
*
|
||||
* @param map[out] The hash map uninitialized
|
||||
*/
|
||||
void hm_init(struct hashmap *map);
|
||||
|
||||
/* Insert a new key in the hash map */
|
||||
void hm_insert(struct hashmap *map, int sockfd, struct sockaddr_storage *sas);
|
||||
/**
|
||||
* @brief Inserts a key in the hash map
|
||||
*
|
||||
* @param map[out] The hash map
|
||||
* @param sockfd[in] The file descriptor (value)
|
||||
* @param sas[in] The sockaddr (value)
|
||||
*/
|
||||
void hm_push(struct hashmap *map, int sockfd, struct sockaddr_storage *sas);
|
||||
|
||||
/* Search for a key in the hash map */
|
||||
/**
|
||||
* @brief Searches for a key in the hash map
|
||||
*
|
||||
* @param map[in] The hash map
|
||||
* @param sockfd[in] The file descriptor (key)
|
||||
* @return struct hashmap* Returns NULL or the key pointer
|
||||
*/
|
||||
struct hashmap *hm_lookup(struct hashmap *map, int sockfd);
|
||||
|
||||
/* Clean up the hash map */
|
||||
/**
|
||||
* @brief Cleans the hash map
|
||||
*
|
||||
* @param map[out] The hash map
|
||||
*/
|
||||
void hm_free(struct hashmap *map);
|
||||
|
||||
void hm_insert(struct hashmap *map, int sockfd, struct sockaddr_storage *sas);
|
||||
|
||||
#endif
|
||||
@@ -3,6 +3,7 @@
|
||||
int hash(int sockfd) { return sockfd % HASHMAP_MAX_CLIENTS; }
|
||||
|
||||
void hm_init(struct hashmap *map) {
|
||||
/* Initialize everything to 0 for the struct, then -1 for fd and next to NULL */
|
||||
memset(map, 0, sizeof(struct hashmap) * HASHMAP_MAX_CLIENTS);
|
||||
|
||||
for (size_t i = 0; i < HASHMAP_MAX_CLIENTS; ++i) {
|
||||
@@ -11,21 +12,23 @@ void hm_init(struct hashmap *map) {
|
||||
}
|
||||
}
|
||||
|
||||
/* This function will add a key even if it exists (use hm_push() instead) */
|
||||
void hm_insert(struct hashmap *map, int sockfd, struct sockaddr_storage *sas) {
|
||||
int index = hash(sockfd);
|
||||
|
||||
if (map[index].sockfd == -1) {
|
||||
/* Current slot is empty */
|
||||
map[index].sockfd = sockfd;
|
||||
map[index].sas = *sas;
|
||||
map[index].next = NULL;
|
||||
} else {
|
||||
/* Go through the linked list and append the new item */
|
||||
struct hashmap *p;
|
||||
for (p = &map[index]; p->next != NULL; p = p->next);
|
||||
/* Append the new key to the head (not the first element because it belongs to the array) of the linked
|
||||
* list */
|
||||
struct hashmap *p = &map[index];
|
||||
struct hashmap *new = malloc(sizeof(struct hashmap));
|
||||
new->sockfd = sockfd;
|
||||
new->sas = *sas;
|
||||
new->next = NULL;
|
||||
|
||||
new->next = p->next;
|
||||
p->next = new;
|
||||
}
|
||||
}
|
||||
@@ -35,7 +38,7 @@ struct hashmap *hm_lookup(struct hashmap *map, int sockfd) {
|
||||
|
||||
if (map[index].sockfd != sockfd) {
|
||||
struct hashmap *p;
|
||||
for (p = map[index].next; p->sockfd != sockfd; p = p->next);
|
||||
for (p = map[index].next; p != NULL && p->sockfd != sockfd; p = p->next);
|
||||
return p;
|
||||
} else {
|
||||
return &map[index];
|
||||
@@ -44,4 +47,25 @@ struct hashmap *hm_lookup(struct hashmap *map, int sockfd) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void hm_free(struct hashmap *map) {}
|
||||
void hm_push(struct hashmap *map, int sockfd, struct sockaddr_storage *sas) {
|
||||
if (hm_lookup(map, sockfd) == NULL) {
|
||||
hm_insert(map, sockfd, sas);
|
||||
}
|
||||
}
|
||||
|
||||
void hm_free(struct hashmap *map) {
|
||||
struct hashmap *p, *next;
|
||||
|
||||
for (size_t i = 0; i < HASHMAP_MAX_CLIENTS; ++i) {
|
||||
if (map[i].next != NULL) {
|
||||
/* Free the malloc */
|
||||
p = map[i].next;
|
||||
next = p->next;
|
||||
do {
|
||||
free(p);
|
||||
p = next;
|
||||
next = p != NULL ? p->next : NULL;
|
||||
} while (p != NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ void handle_clients(int sockfd) {
|
||||
|
||||
setnonblocking(client_fd);
|
||||
epoll_ctl_add(epfd, client_fd, EPOLLIN);
|
||||
hm_insert(clients, client_fd, &their_sa);
|
||||
hm_push(clients, client_fd, &their_sa);
|
||||
|
||||
int bytes_sent = send(client_fd, msg, msg_len, 0);
|
||||
fprintf(stdout, "[server] Sent %d bytes\n", bytes_sent);
|
||||
@@ -113,9 +113,13 @@ void handle_clients(int sockfd) {
|
||||
free(revents);
|
||||
close(epfd);
|
||||
|
||||
/* Close all the file descriptors */
|
||||
for (size_t i = 0; i < HASHMAP_MAX_CLIENTS; ++i) {
|
||||
close(clients[i].sockfd);
|
||||
/* TODO: close collisions */
|
||||
}
|
||||
|
||||
hm_free(clients);
|
||||
}
|
||||
|
||||
void epoll_ctl_add(int epfd, int sockfd, uint32_t events) {
|
||||
|
||||
Reference in New Issue
Block a user