diff options
author | Anna Henningsen <anna@addaleax.net> | 2017-08-14 20:38:04 +0200 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2017-08-17 20:26:59 +0200 |
commit | 491cc76871c4bf9351ef6246b3cc6948c37d84f9 (patch) | |
tree | 2a045bd67f4aeed8d2d00c3fdfd0760ecbee3549 /src/cares_wrap.cc | |
parent | 9e08695f85d4273f01e010cf384f42030d66b453 (diff) | |
download | android-node-v8-491cc76871c4bf9351ef6246b3cc6948c37d84f9.tar.gz android-node-v8-491cc76871c4bf9351ef6246b3cc6948c37d84f9.tar.bz2 android-node-v8-491cc76871c4bf9351ef6246b3cc6948c37d84f9.zip |
src: use `unordered_set` instead of custom rb tree
Use a standard hash-based container instead of the custom included
red/black tree implementation. There is likely no noticeable
performance difference, and if there is one, it is very likely
to be an improvement.
PR-URL: https://github.com/nodejs/node/pull/14826
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Diffstat (limited to 'src/cares_wrap.cc')
-rw-r--r-- | src/cares_wrap.cc | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 7869651a45..f43eb7ed8b 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -28,7 +28,6 @@ #include "node.h" #include "req-wrap.h" #include "req-wrap-inl.h" -#include "tree.h" #include "util.h" #include "util-inl.h" #include "uv.h" @@ -37,6 +36,7 @@ #include <stdlib.h> #include <string.h> #include <vector> +#include <unordered_set> #if defined(__ANDROID__) || \ defined(__MINGW32__) || \ @@ -122,10 +122,22 @@ struct node_ares_task { ChannelWrap* channel; ares_socket_t sock; uv_poll_t poll_watcher; - RB_ENTRY(node_ares_task) node; }; -RB_HEAD(node_ares_task_list, node_ares_task); +struct TaskHash { + size_t operator()(node_ares_task* a) const { + return std::hash<ares_socket_t>()(a->sock); + } +}; + +struct TaskEqual { + inline bool operator()(node_ares_task* a, node_ares_task* b) const { + return a->sock == b->sock; + } +}; + +using node_ares_task_list = + std::unordered_set<node_ares_task*, TaskHash, TaskEqual>; class ChannelWrap : public AsyncWrap { public: @@ -169,8 +181,6 @@ ChannelWrap::ChannelWrap(Environment* env, query_last_ok_(true), is_servers_default_(true), library_inited_(false) { - RB_INIT(&task_list_); - MakeWeak<ChannelWrap>(this); Setup(); @@ -222,25 +232,12 @@ GetNameInfoReqWrap::~GetNameInfoReqWrap() { } -int cmp_ares_tasks(const node_ares_task* a, const node_ares_task* b) { - if (a->sock < b->sock) - return -1; - if (a->sock > b->sock) - return 1; - return 0; -} - - -RB_GENERATE_STATIC(node_ares_task_list, node_ares_task, node, cmp_ares_tasks) - - - /* This is called once per second by loop->timer. It is used to constantly */ /* call back into c-ares for possibly processing timeouts. */ void ChannelWrap::AresTimeout(uv_timer_t* handle) { ChannelWrap* channel = static_cast<ChannelWrap*>(handle->data); CHECK_EQ(channel->timer_handle(), handle); - CHECK_EQ(false, RB_EMPTY(channel->task_list())); + CHECK_EQ(false, channel->task_list()->empty()); ares_process_fd(channel->cares_channel(), ARES_SOCKET_BAD, ARES_SOCKET_BAD); } @@ -306,7 +303,9 @@ void ares_sockstate_cb(void* data, node_ares_task lookup_task; lookup_task.sock = sock; - task = RB_FIND(node_ares_task_list, channel->task_list(), &lookup_task); + auto it = channel->task_list()->find(&lookup_task); + + task = (it == channel->task_list()->end()) ? nullptr : *it; if (read || write) { if (!task) { @@ -315,7 +314,7 @@ void ares_sockstate_cb(void* data, /* If this is the first socket then start the timer. */ uv_timer_t* timer_handle = channel->timer_handle(); if (!uv_is_active(reinterpret_cast<uv_handle_t*>(timer_handle))) { - CHECK(RB_EMPTY(channel->task_list())); + CHECK(channel->task_list()->empty()); uv_timer_start(timer_handle, ChannelWrap::AresTimeout, 1000, 1000); } @@ -327,7 +326,7 @@ void ares_sockstate_cb(void* data, return; } - RB_INSERT(node_ares_task_list, channel->task_list(), task); + channel->task_list()->insert(task); } /* This should never fail. If it fails anyway, the query will eventually */ @@ -343,11 +342,11 @@ void ares_sockstate_cb(void* data, CHECK(task && "When an ares socket is closed we should have a handle for it"); - RB_REMOVE(node_ares_task_list, channel->task_list(), task); + channel->task_list()->erase(it); uv_close(reinterpret_cast<uv_handle_t*>(&task->poll_watcher), ares_poll_close_cb); - if (RB_EMPTY(channel->task_list())) { + if (channel->task_list()->empty()) { uv_timer_stop(channel->timer_handle()); } } |