src: apply a modest performance perf to permissions · nodejs/node@d4ced88 · GitHub
Skip to content

Commit d4ced88

Browse files
jasnelladuh95
authored andcommitted
src: apply a modest performance perf to permissions
Improve the way the RadixTree works and apply a fast api call. Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: #65158 Reviewed-By: Xuguang Mei <meixuguang@gmail.com> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
1 parent efb649e commit d4ced88

3 files changed

Lines changed: 93 additions & 35 deletions

File tree

src/permission/fs_permission.cc

Lines changed: 9 additions & 12 deletions

src/permission/fs_permission.h

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
#include "v8.h"
77

8-
#include <unordered_map>
8+
#include <vector>
99
#include "permission/permission_base.h"
1010
#include "util.h"
1111

@@ -28,16 +28,30 @@ class FSPermission final : public PermissionBase {
2828
struct RadixTree {
2929
struct Node {
3030
std::string prefix;
31-
std::unordered_map<char, Node*> children;
32-
Node* wildcard_child;
33-
bool is_leaf;
31+
std::vector<std::pair<char, Node*>> children;
32+
Node* wildcard_child = nullptr;
33+
bool is_leaf = false;
3434

35-
explicit Node(const std::string& pre)
36-
: prefix(pre), wildcard_child(nullptr), is_leaf(false) {}
35+
explicit Node(std::string_view pre)
36+
: prefix(pre) {}
3737

38-
Node() : wildcard_child(nullptr), is_leaf(false) {}
38+
Node() = default;
3939

40-
Node* CreateChild(const std::string& path_prefix) {
40+
Node* FindChild(char label) const {
41+
for (const auto& [c, node] : children) {
42+
if (c == label) return node;
43+
}
44+
return nullptr;
45+
}
46+
47+
void SetChild(char label, Node* node) {
48+
for (auto& [c, n] : children) {
49+
if (c == label) { n = node; return; }
50+
}
51+
children.emplace_back(label, node);
52+
}
53+
54+
Node* CreateChild(std::string_view path_prefix) {
4155
if (path_prefix.empty() && !is_leaf) {
4256
is_leaf = true;
4357
return this;
@@ -46,10 +60,11 @@ class FSPermission final : public PermissionBase {
4660
CHECK(!path_prefix.empty());
4761
char label = path_prefix[0];
4862

49-
Node* child = children[label];
63+
Node* child = FindChild(label);
5064
if (child == nullptr) {
51-
children[label] = new Node(path_prefix);
52-
return children[label];
65+
child = new Node(path_prefix);
66+
children.emplace_back(label, child);
67+
return child;
5368
}
5469
bool child_was_end_node = child->IsEndNode();
5570

@@ -58,13 +73,13 @@ class FSPermission final : public PermissionBase {
5873
size_t prefix_len = path_prefix.length();
5974
for (; i < child->prefix.length(); ++i) {
6075
if (i >= prefix_len || path_prefix[i] != child->prefix[i]) {
61-
std::string parent_prefix = child->prefix.substr(0, i);
62-
std::string child_prefix = child->prefix.substr(i);
76+
std::string parent_prefix(child->prefix.substr(0, i));
77+
std::string child_prefix(child->prefix.substr(i));
6378

6479
child->prefix = child_prefix;
6580
Node* split_child = new Node(parent_prefix);
66-
split_child->children[child_prefix[0]] = child;
67-
children[parent_prefix[0]] = split_child;
81+
split_child->children.emplace_back(child_prefix[0], child);
82+
SetChild(parent_prefix[0], split_child);
6883

6984
return split_child->CreateChild(path_prefix.substr(i));
7085
}
@@ -83,24 +98,23 @@ class FSPermission final : public PermissionBase {
8398
return wildcard_child;
8499
}
85100

86-
Node* NextNode(const std::string& path, size_t idx) const {
101+
Node* NextNode(std::string_view path, size_t idx) const {
87102
if (idx >= path.length()) {
88103
return nullptr;
89104
}
90105

91106
// wildcard node takes precedence
92107
if (children.size() > 1) {
93-
auto it = children.find('*');
94-
if (it != children.end()) {
95-
return it->second;
108+
Node* wc = FindChild('*');
109+
if (wc != nullptr) {
110+
return wc;
96111
}
97112
}
98113

99-
auto it = children.find(path[idx]);
100-
if (it == children.end()) {
114+
Node* child = FindChild(path[idx]);
115+
if (child == nullptr) {
101116
return nullptr;
102117
}
103-
auto child = it->second;
104118
// match prefix
105119
size_t prefix_len = child->prefix.length();
106120
for (size_t i = 0; i < path.length(); ++i) {

src/permission/permission.cc

Lines changed: 48 additions & 1 deletion

0 commit comments

Comments
 (0)