Skip to content

Commit 2e01445

Browse files
committed
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: #14826 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Daniel Bevenius <[email protected]> Reviewed-By: Tobias Nießen <[email protected]>
1 parent 60f2fa9 commit 2e01445

File tree

6 files changed

+23
-802
lines changed

6 files changed

+23
-802
lines changed

Makefile

-2
Original file line numberDiff line numberDiff line change
@@ -891,8 +891,6 @@ jslint-ci:
891891

892892
CPPLINT_EXCLUDE ?=
893893
CPPLINT_EXCLUDE += src/node_root_certs.h
894-
CPPLINT_EXCLUDE += src/queue.h
895-
CPPLINT_EXCLUDE += src/tree.h
896894
CPPLINT_EXCLUDE += $(wildcard test/addons/??_*/*.cc test/addons/??_*/*.h)
897895
CPPLINT_EXCLUDE += $(wildcard test/addons-napi/??_*/*.cc test/addons-napi/??_*/*.h)
898896
# These files were copied more or less verbatim from V8.

node.gyp

-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,6 @@
260260
'src/tracing/node_trace_buffer.h',
261261
'src/tracing/node_trace_writer.h',
262262
'src/tracing/trace_event.h'
263-
'src/tree.h',
264263
'src/util.h',
265264
'src/util-inl.h',
266265
'deps/http_parser/http_parser.h',

src/cares_wrap.cc

+23-24
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#include "node.h"
2929
#include "req-wrap.h"
3030
#include "req-wrap-inl.h"
31-
#include "tree.h"
3231
#include "util.h"
3332
#include "util-inl.h"
3433
#include "uv.h"
@@ -37,6 +36,7 @@
3736
#include <stdlib.h>
3837
#include <string.h>
3938
#include <vector>
39+
#include <unordered_set>
4040

4141
#if defined(__ANDROID__) || \
4242
defined(__MINGW32__) || \
@@ -122,10 +122,22 @@ struct node_ares_task {
122122
ChannelWrap* channel;
123123
ares_socket_t sock;
124124
uv_poll_t poll_watcher;
125-
RB_ENTRY(node_ares_task) node;
126125
};
127126

128-
RB_HEAD(node_ares_task_list, node_ares_task);
127+
struct TaskHash {
128+
size_t operator()(node_ares_task* a) const {
129+
return std::hash<ares_socket_t>()(a->sock);
130+
}
131+
};
132+
133+
struct TaskEqual {
134+
inline bool operator()(node_ares_task* a, node_ares_task* b) const {
135+
return a->sock == b->sock;
136+
}
137+
};
138+
139+
using node_ares_task_list =
140+
std::unordered_set<node_ares_task*, TaskHash, TaskEqual>;
129141

130142
class ChannelWrap : public AsyncWrap {
131143
public:
@@ -169,8 +181,6 @@ ChannelWrap::ChannelWrap(Environment* env,
169181
query_last_ok_(true),
170182
is_servers_default_(true),
171183
library_inited_(false) {
172-
RB_INIT(&task_list_);
173-
174184
MakeWeak<ChannelWrap>(this);
175185

176186
Setup();
@@ -222,25 +232,12 @@ GetNameInfoReqWrap::~GetNameInfoReqWrap() {
222232
}
223233

224234

225-
int cmp_ares_tasks(const node_ares_task* a, const node_ares_task* b) {
226-
if (a->sock < b->sock)
227-
return -1;
228-
if (a->sock > b->sock)
229-
return 1;
230-
return 0;
231-
}
232-
233-
234-
RB_GENERATE_STATIC(node_ares_task_list, node_ares_task, node, cmp_ares_tasks)
235-
236-
237-
238235
/* This is called once per second by loop->timer. It is used to constantly */
239236
/* call back into c-ares for possibly processing timeouts. */
240237
void ChannelWrap::AresTimeout(uv_timer_t* handle) {
241238
ChannelWrap* channel = static_cast<ChannelWrap*>(handle->data);
242239
CHECK_EQ(channel->timer_handle(), handle);
243-
CHECK_EQ(false, RB_EMPTY(channel->task_list()));
240+
CHECK_EQ(false, channel->task_list()->empty());
244241
ares_process_fd(channel->cares_channel(), ARES_SOCKET_BAD, ARES_SOCKET_BAD);
245242
}
246243

@@ -306,7 +303,9 @@ void ares_sockstate_cb(void* data,
306303

307304
node_ares_task lookup_task;
308305
lookup_task.sock = sock;
309-
task = RB_FIND(node_ares_task_list, channel->task_list(), &lookup_task);
306+
auto it = channel->task_list()->find(&lookup_task);
307+
308+
task = (it == channel->task_list()->end()) ? nullptr : *it;
310309

311310
if (read || write) {
312311
if (!task) {
@@ -315,7 +314,7 @@ void ares_sockstate_cb(void* data,
315314
/* If this is the first socket then start the timer. */
316315
uv_timer_t* timer_handle = channel->timer_handle();
317316
if (!uv_is_active(reinterpret_cast<uv_handle_t*>(timer_handle))) {
318-
CHECK(RB_EMPTY(channel->task_list()));
317+
CHECK(channel->task_list()->empty());
319318
uv_timer_start(timer_handle, ChannelWrap::AresTimeout, 1000, 1000);
320319
}
321320

@@ -327,7 +326,7 @@ void ares_sockstate_cb(void* data,
327326
return;
328327
}
329328

330-
RB_INSERT(node_ares_task_list, channel->task_list(), task);
329+
channel->task_list()->insert(task);
331330
}
332331

333332
/* This should never fail. If it fails anyway, the query will eventually */
@@ -343,11 +342,11 @@ void ares_sockstate_cb(void* data,
343342
CHECK(task &&
344343
"When an ares socket is closed we should have a handle for it");
345344

346-
RB_REMOVE(node_ares_task_list, channel->task_list(), task);
345+
channel->task_list()->erase(it);
347346
uv_close(reinterpret_cast<uv_handle_t*>(&task->poll_watcher),
348347
ares_poll_close_cb);
349348

350-
if (RB_EMPTY(channel->task_list())) {
349+
if (channel->task_list()->empty()) {
351350
uv_timer_stop(channel->timer_handle());
352351
}
353352
}

src/env.h

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#endif
3131
#include "handle_wrap.h"
3232
#include "req-wrap.h"
33-
#include "tree.h"
3433
#include "util.h"
3534
#include "uv.h"
3635
#include "v8.h"

0 commit comments

Comments
 (0)