diff --git a/src/core/usermanager.c b/src/core/usermanager.c index 756d313..345a98b 100644 --- a/src/core/usermanager.c +++ b/src/core/usermanager.c @@ -38,6 +38,11 @@ static void clear_user_list_callback(void* ptr) } } +static int uman_map_compare(const void* a, const void* b) +{ + return strcmp((const char*) a, (const char*) b); +} + struct hub_user_manager* uman_init() { @@ -46,15 +51,10 @@ struct hub_user_manager* uman_init() return NULL; users->list = list_create(); + users->nickmap = rb_tree_create(uman_map_compare, NULL, NULL); + users->cidmap = rb_tree_create(uman_map_compare, NULL, NULL); users->sids = sid_pool_create(net_get_max_sockets()); - if (!users->list) - { - list_destroy(users->list); - hub_free(users); - return NULL; - } - return users; } @@ -64,11 +64,18 @@ int uman_shutdown(struct hub_user_manager* users) if (!users) return -1; + if (users->nickmap) + rb_tree_destroy(users->nickmap); + + if (users->cidmap) + rb_tree_destroy(users->cidmap); + if (users->list) { list_clear(users->list, &clear_user_list_callback); list_destroy(users->list); } + sid_pool_destroy(users->sids); hub_free(users); @@ -81,6 +88,9 @@ int uman_add(struct hub_user_manager* users, struct hub_user* user) if (!users || !user) return -1; + rb_tree_insert(users->nickmap, user->id.nick, user); + rb_tree_insert(users->cidmap, user->id.cid, user); + list_append(users->list, user); users->count++; users->count_peak = MAX(users->count, users->count_peak); @@ -96,6 +106,8 @@ int uman_remove(struct hub_user_manager* users, struct hub_user* user) return -1; list_remove(users->list, user); + rb_tree_remove(users->nickmap, user->id.nick); + rb_tree_remove(users->cidmap, user->id.cid); if (users->count > 0) { @@ -120,25 +132,15 @@ struct hub_user* uman_get_user_by_sid(struct hub_user_manager* users, sid_t sid) struct hub_user* uman_get_user_by_cid(struct hub_user_manager* users, const char* cid) { - struct hub_user* user; - LIST_FOREACH(struct hub_user*, user, users->list, - { - if (strcmp(user->id.cid, cid) == 0) - return user; - }); - return NULL; + struct hub_user* user = (struct hub_user*) rb_tree_get(users->cidmap, (const void*) cid); + return user; } struct hub_user* uman_get_user_by_nick(struct hub_user_manager* users, const char* nick) { - struct hub_user* user; - LIST_FOREACH(struct hub_user*, user, users->list, - { - if (strcmp(user->id.nick, nick) == 0) - return user; - }); - return NULL; + struct hub_user* user = (struct hub_user*) rb_tree_get(users->nickmap, nick); + return user; } size_t uman_get_user_by_addr(struct hub_user_manager* users, struct linked_list* target, struct ip_range* range) diff --git a/src/core/usermanager.h b/src/core/usermanager.h index 00512db..e258627 100644 --- a/src/core/usermanager.h +++ b/src/core/usermanager.h @@ -24,10 +24,12 @@ struct hub_user_manager { size_t count; /**<< "Number of all fully connected and logged in users" */ size_t count_peak; /**<< "Peak number of users" */ - struct sid_pool* sids; uint64_t shared_size; /**<< "The total number of shared bytes among fully connected users." */ uint64_t shared_files; /**<< "The total number of shared files among fully connected users." */ + struct sid_pool* sids; /**<< "Maps SIDs to users (constant time)" */ struct linked_list* list; /**<< "Contains all logged in users" */ + struct rb_tree* nickmap; /**<< "Maps nicknames to users (red black tree)" */ + struct rb_tree* cidmap; /**<< "Maps CIDs to users (red black tree)" */ }; /** diff --git a/src/uhub.h b/src/uhub.h index a7e92c7..f078d76 100644 --- a/src/uhub.h +++ b/src/uhub.h @@ -69,6 +69,7 @@ extern "C" { #include "util/misc.h" #include "util/tiger.h" #include "util/threads.h" +#include "util/rbtree.h" #include "adc/sid.h" #include "adc/message.h" diff --git a/src/util/rbtree.c b/src/util/rbtree.c index 57cb271..33f7841 100644 --- a/src/util/rbtree.c +++ b/src/util/rbtree.c @@ -157,7 +157,7 @@ static struct rb_node* rb_tree_insert_r(struct rb_tree* tree, struct rb_node* no struct rb_tree* rb_tree_create(rb_tree_compare compare, rb_tree_alloc a, rb_tree_free f) { - struct rb_tree* tree = a(sizeof(struct rb_tree)); + struct rb_tree* tree = a ? a(sizeof(struct rb_tree)) : hub_malloc(sizeof(struct rb_tree)); tree->compare = compare; tree->alloc = a ? a : hub_malloc; tree->free = f ? f : hub_free;