Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Merge pull request #462 from EOSIO/stackless-rope
Browse files Browse the repository at this point in the history
rope::c_str(): don't recurse
  • Loading branch information
larryk85 committed Mar 21, 2019
2 parents 68f8eba + 4376af9 commit 4da01cb
Showing 1 changed file with 60 additions and 18 deletions.
78 changes: 60 additions & 18 deletions libraries/eosiolib/core/eosio/rope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,21 @@ namespace eosio {
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

namespace impl {
struct str_t;
struct concat_t;
typedef std::variant<concat_t, str_t> rope_node;

struct str_t {
const char* c_str;
size_t size;
const char* c_str;
size_t size;
mutable const rope_node* temp = nullptr;
};

struct concat_t;
typedef std::variant<concat_t, str_t> rope_node;
struct concat_t {
rope_node* left = nullptr;
rope_node* right = nullptr;
rope_node* left = nullptr;
rope_node* right = nullptr;
mutable const rope_node* temp = nullptr;
mutable bool temp_left = false;
};
}

Expand All @@ -38,21 +43,58 @@ namespace eosio {
return i;
}

void c_str(char* buffer, const rope_node* r, size_t& off)const {
static void c_str(char* buffer, const rope_node* r, size_t& off) {
bool going_down = true;
if (r) {
std::visit(overloaded {
[&](const concat_t& c) {
if (c.left)
c_str(buffer, c.left, off);
if (c.right)
c_str(buffer, c.right, off);
},
[&](const str_t& s) {
off -= s.size;
memcpy(buffer+off, s.c_str, s.size);
}
std::visit([](const auto& n) {
n.temp = nullptr;
}, *r);
}
while (r) {
if (going_down) {
std::visit(overloaded {
[&](const concat_t& c) {
if (c.left) {
c.temp_left = true;
std::visit([&](const auto& n){
n.temp = r;
}, *c.left);
going_down = true;
r = c.left;
} else if (c.right) {
c.temp_left = false;
std::visit([&](const auto& n){
n.temp = r;
}, *c.right);
going_down = true;
r = c.right;
} else {
going_down = false;
r = c.temp;
}
},
[&](const str_t& s) {
off -= s.size;
memcpy(buffer+off, s.c_str, s.size);
going_down = false;
r = s.temp;
}
}, *r);
} else {
const auto& c = std::get<concat_t>(*r);
if (c.temp_left && c.right) {
c.temp_left = false;
std::visit([&](const auto& n){
n.temp = r;
}, *c.right);
going_down = true;
r = c.right;
} else {
going_down = false;
r = c.temp;
}
}
}
}

void append(rope_node* rn, bool use_left=false) {
Expand Down

0 comments on commit 4da01cb

Please sign in to comment.