fix hashmap
This commit is contained in:
@@ -14,19 +14,46 @@ struct hashmap {
|
|||||||
struct hashmap *next;
|
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);
|
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);
|
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);
|
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_free(struct hashmap *map);
|
||||||
|
|
||||||
|
void hm_insert(struct hashmap *map, int sockfd, struct sockaddr_storage *sas);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
int hash(int sockfd) { return sockfd % HASHMAP_MAX_CLIENTS; }
|
int hash(int sockfd) { return sockfd % HASHMAP_MAX_CLIENTS; }
|
||||||
|
|
||||||
void hm_init(struct hashmap *map) {
|
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);
|
memset(map, 0, sizeof(struct hashmap) * HASHMAP_MAX_CLIENTS);
|
||||||
|
|
||||||
for (size_t i = 0; i < HASHMAP_MAX_CLIENTS; ++i) {
|
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) {
|
void hm_insert(struct hashmap *map, int sockfd, struct sockaddr_storage *sas) {
|
||||||
int index = hash(sockfd);
|
int index = hash(sockfd);
|
||||||
|
|
||||||
if (map[index].sockfd == -1) {
|
if (map[index].sockfd == -1) {
|
||||||
|
/* Current slot is empty */
|
||||||
map[index].sockfd = sockfd;
|
map[index].sockfd = sockfd;
|
||||||
map[index].sas = *sas;
|
map[index].sas = *sas;
|
||||||
|
map[index].next = NULL;
|
||||||
} else {
|
} else {
|
||||||
/* Go through the linked list and append the new item */
|
/* Append the new key to the head (not the first element because it belongs to the array) of the linked
|
||||||
struct hashmap *p;
|
* list */
|
||||||
for (p = &map[index]; p->next != NULL; p = p->next);
|
struct hashmap *p = &map[index];
|
||||||
struct hashmap *new = malloc(sizeof(struct hashmap));
|
struct hashmap *new = malloc(sizeof(struct hashmap));
|
||||||
new->sockfd = sockfd;
|
new->sockfd = sockfd;
|
||||||
new->sas = *sas;
|
new->sas = *sas;
|
||||||
new->next = NULL;
|
new->next = p->next;
|
||||||
|
|
||||||
p->next = new;
|
p->next = new;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,7 +38,7 @@ struct hashmap *hm_lookup(struct hashmap *map, int sockfd) {
|
|||||||
|
|
||||||
if (map[index].sockfd != sockfd) {
|
if (map[index].sockfd != sockfd) {
|
||||||
struct hashmap *p;
|
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;
|
return p;
|
||||||
} else {
|
} else {
|
||||||
return &map[index];
|
return &map[index];
|
||||||
@@ -44,4 +47,25 @@ struct hashmap *hm_lookup(struct hashmap *map, int sockfd) {
|
|||||||
return NULL;
|
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);
|
setnonblocking(client_fd);
|
||||||
epoll_ctl_add(epfd, client_fd, EPOLLIN);
|
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);
|
int bytes_sent = send(client_fd, msg, msg_len, 0);
|
||||||
fprintf(stdout, "[server] Sent %d bytes\n", bytes_sent);
|
fprintf(stdout, "[server] Sent %d bytes\n", bytes_sent);
|
||||||
@@ -113,9 +113,13 @@ void handle_clients(int sockfd) {
|
|||||||
free(revents);
|
free(revents);
|
||||||
close(epfd);
|
close(epfd);
|
||||||
|
|
||||||
|
/* Close all the file descriptors */
|
||||||
for (size_t i = 0; i < HASHMAP_MAX_CLIENTS; ++i) {
|
for (size_t i = 0; i < HASHMAP_MAX_CLIENTS; ++i) {
|
||||||
close(clients[i].sockfd);
|
close(clients[i].sockfd);
|
||||||
|
/* TODO: close collisions */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hm_free(clients);
|
||||||
}
|
}
|
||||||
|
|
||||||
void epoll_ctl_add(int epfd, int sockfd, uint32_t events) {
|
void epoll_ctl_add(int epfd, int sockfd, uint32_t events) {
|
||||||
|
|||||||
Reference in New Issue
Block a user