Skip to content

Commit

Permalink
epee: faster, though would need c++14 to be noticeably faster...
Browse files Browse the repository at this point in the history
  • Loading branch information
moneromooo-monero committed Mar 25, 2019
1 parent 59776a6 commit b831e30
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 59 deletions.
32 changes: 30 additions & 2 deletions contrib/epee/include/storages/parserse_base_utils.h
Expand Up @@ -30,11 +30,30 @@

#include <algorithm>
#include <boost/utility/string_ref.hpp>
#include <boost/optional.hpp>

namespace epee
{
namespace misc_utils
{
class backed_string_ref: public boost::string_ref
{
public:
backed_string_ref(): boost::string_ref() {}
backed_string_ref(const char *ptr, size_t n): boost::string_ref(ptr, n) {}
backed_string_ref(const std::string &s): backing_string(s) { *(boost::string_ref*)this = boost::string_ref(backing_string->data(), backing_string->size()); }

std::string take_string()
{
if (backing_string)
return std::move(*backing_string);
return std::string(data(), size());
}

private:
boost::optional<std::string> backing_string;
};

namespace parse
{
// 1: digit
Expand Down Expand Up @@ -125,14 +144,22 @@ namespace misc_utils
\\ Backslash character
*/
inline void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
inline void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, backed_string_ref& sval)
{
bool escape_mode = false;
std::string::const_iterator it = star_end_string;
++it;
std::string::const_iterator fi = it;
while (fi != buf_end && ((lut[(uint8_t)*fi] & 32)) == 0)
++fi;
if (fi == buf_end || *fi == '\"')
{
// common case, no escapes, we don't need backing
star_end_string = fi;
sval = backed_string_ref(&*it, std::distance(it, fi));
return;
}
std::string val;
val.assign(it, fi);
val.reserve(std::distance(star_end_string, buf_end));
it = fi;
Expand Down Expand Up @@ -170,6 +197,7 @@ namespace misc_utils
}else if(*it == '"')
{
star_end_string = it;
sval = backed_string_ref(std::move(val));
return;
}else if(*it == '\\')
{
Expand All @@ -182,7 +210,7 @@ namespace misc_utils
}
ASSERT_MES_AND_THROW("Failed to match string in json entry: " << std::string(star_end_string, buf_end));
}
inline bool match_string(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val)
inline bool match_string(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, backed_string_ref& val)
{
try
{
Expand Down
95 changes: 45 additions & 50 deletions contrib/epee/include/storages/portable_storage.h
Expand Up @@ -54,31 +54,31 @@ namespace epee

portable_storage(){}
virtual ~portable_storage(){}
hsection open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist = false);
hsection open_section(const boost::string_ref& section_name, hsection hparent_section, bool create_if_notexist = false);
template<class t_value>
bool get_value(const std::string& value_name, t_value& val, hsection hparent_section);
bool get_value(const std::string& value_name, storage_entry& val, hsection hparent_section);
bool get_value(const boost::string_ref& value_name, t_value& val, hsection hparent_section);
bool get_value(const boost::string_ref& value_name, storage_entry& val, hsection hparent_section);
template<class t_value>
bool set_value(const std::string& value_name, const t_value& target, hsection hparent_section);
bool set_value(const boost::string_ref& value_name, const t_value& target, hsection hparent_section);

//serial access for arrays of values --------------------------------------
//values
template<class t_value>
harray get_first_value(const std::string& value_name, t_value& target, hsection hparent_section);
harray get_first_value(const boost::string_ref& value_name, t_value& target, hsection hparent_section);
template<class t_value>
bool get_next_value(harray hval_array, t_value& target);
template<class t_value>
harray insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section);
harray insert_first_value(const boost::string_ref& value_name, const t_value& target, hsection hparent_section);
template<class t_value>
bool insert_next_value(harray hval_array, const t_value& target);
//sections
harray get_first_section(const std::string& pSectionName, hsection& h_child_section, hsection hparent_section);
harray get_first_section(const boost::string_ref& pSectionName, hsection& h_child_section, hsection hparent_section);
bool get_next_section(harray hSecArray, hsection& h_child_section);
harray insert_first_section(const std::string& pSectionName, hsection& hinserted_childsection, hsection hparent_section);
harray insert_first_section(const boost::string_ref& pSectionName, hsection& hinserted_childsection, hsection hparent_section);
bool insert_next_section(harray hSecArray, hsection& hinserted_childsection);
//------------------------------------------------------------------------
//delete entry (section, value or array)
bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr);
bool delete_entry(const boost::string_ref& pentry_name, hsection hparent_section = nullptr);

//-------------------------------------------------------------------------------
bool store_to_binary(binarybuffer& target);
Expand All @@ -92,11 +92,12 @@ namespace epee
private:
section m_root;
hsection get_root_section() {return &m_root;}
storage_entry* find_storage_entry(const std::string& pentry_name, hsection psection);
storage_entry* find_storage_entry(const boost::string_ref& pentry_name, hsection psection);
storage_entry* find_or_create_storage_entry(const boost::string_ref& pentry_name, hsection psection);
template<class entry_type>
storage_entry* insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, const entry_type& entry);
storage_entry* insert_new_entry_get_storage_entry(const boost::string_ref& pentry_name, hsection psection, const entry_type& entry);

hsection insert_new_section(const std::string& pentry_name, hsection psection);
hsection insert_new_section(const boost::string_ref& pentry_name, hsection psection);

#pragma pack(push)
#pragma pack(1)
Expand Down Expand Up @@ -177,17 +178,15 @@ namespace epee
}
//---------------------------------------------------------------------------------------------------------------
inline
hsection portable_storage::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist)
hsection portable_storage::open_section(const boost::string_ref& section_name, hsection hparent_section, bool create_if_notexist)
{
TRY_ENTRY();
hparent_section = hparent_section ? hparent_section:&m_root;
storage_entry* pentry = find_storage_entry(section_name, hparent_section);
if(!pentry)
{
if(!create_if_notexist)
return nullptr;
return insert_new_section(section_name, hparent_section);
}
storage_entry* pentry;
if (create_if_notexist)
pentry = find_or_create_storage_entry(section_name, hparent_section);
else
pentry = find_storage_entry(section_name, hparent_section);
CHECK_AND_ASSERT(pentry , nullptr);
//check that section_entry we find is real "CSSection"
if(pentry->type() != typeid(section))
Expand All @@ -211,7 +210,7 @@ namespace epee
};

template<class t_value>
bool portable_storage::get_value(const std::string& value_name, t_value& val, hsection hparent_section)
bool portable_storage::get_value(const boost::string_ref& value_name, t_value& val, hsection hparent_section)
{
BOOST_MPL_ASSERT(( boost::mpl::contains<storage_entry::types, t_value> ));
//TRY_ENTRY();
Expand All @@ -227,7 +226,7 @@ namespace epee
}
//---------------------------------------------------------------------------------------------------------------
inline
bool portable_storage::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section)
bool portable_storage::get_value(const boost::string_ref& value_name, storage_entry& val, hsection hparent_section)
{
//TRY_ENTRY();
if(!hparent_section) hparent_section = &m_root;
Expand All @@ -241,40 +240,44 @@ namespace epee
}
//---------------------------------------------------------------------------------------------------------------
template<class t_value>
bool portable_storage::set_value(const std::string& value_name, const t_value& v, hsection hparent_section)
bool portable_storage::set_value(const boost::string_ref& value_name, const t_value& v, hsection hparent_section)
{
BOOST_MPL_ASSERT(( boost::mpl::contains<boost::mpl::push_front<storage_entry::types, storage_entry>::type, t_value> ));
TRY_ENTRY();
if(!hparent_section)
hparent_section = &m_root;
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
storage_entry* pentry = find_or_create_storage_entry(value_name, hparent_section);
if(!pentry)
{
pentry = insert_new_entry_get_storage_entry(value_name, hparent_section, v);
if(!pentry)
return false;
return true;
}
return false;
*pentry = storage_entry(v);
return true;
CATCH_ENTRY("portable_storage::template<>set_value", false);
}
//---------------------------------------------------------------------------------------------------------------
inline
storage_entry* portable_storage::find_storage_entry(const std::string& pentry_name, hsection psection)
storage_entry* portable_storage::find_storage_entry(const boost::string_ref& pentry_name, hsection psection)
{
TRY_ENTRY();
CHECK_AND_ASSERT(psection, nullptr);
auto it = psection->m_entries.find(pentry_name);
auto it = psection->m_entries.find(std::string(pentry_name.data(), pentry_name.size()));
if(it == psection->m_entries.end())
return nullptr;

return &it->second;
CATCH_ENTRY("portable_storage::find_storage_entry", nullptr);
}
//---------------------------------------------------------------------------------------------------------------
inline
storage_entry* portable_storage::find_or_create_storage_entry(const boost::string_ref& pentry_name, hsection psection)
{
TRY_ENTRY();
CHECK_AND_ASSERT(psection, nullptr);
return &psection->m_entries[std::string(pentry_name.data(), pentry_name.size())];
CATCH_ENTRY("portable_storage::find_storage_entry", nullptr);
}
//---------------------------------------------------------------------------------------------------------------
template<class entry_type>
storage_entry* portable_storage::insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, const entry_type& entry)
storage_entry* portable_storage::insert_new_entry_get_storage_entry(const boost::string_ref& pentry_name, hsection psection, const entry_type& entry)
{
TRY_ENTRY();
CHECK_AND_ASSERT(psection, nullptr);
Expand All @@ -284,7 +287,7 @@ namespace epee
}
//---------------------------------------------------------------------------------------------------------------
inline
hsection portable_storage::insert_new_section(const std::string& pentry_name, hsection psection)
hsection portable_storage::insert_new_section(const boost::string_ref& pentry_name, hsection psection)
{
TRY_ENTRY();
storage_entry* pse = insert_new_entry_get_storage_entry(pentry_name, psection, section());
Expand All @@ -310,7 +313,7 @@ namespace epee
};
//---------------------------------------------------------------------------------------------------------------
template<class t_value>
harray portable_storage::get_first_value(const std::string& value_name, t_value& target, hsection hparent_section)
harray portable_storage::get_first_value(const boost::string_ref& value_name, t_value& target, hsection hparent_section)
{
BOOST_MPL_ASSERT(( boost::mpl::contains<storage_entry::types, t_value> ));
//TRY_ENTRY();
Expand Down Expand Up @@ -362,17 +365,13 @@ namespace epee
}
//---------------------------------------------------------------------------------------------------------------
template<class t_value>
harray portable_storage::insert_first_value(const std::string& value_name, const t_value& target, hsection hparent_section)
harray portable_storage::insert_first_value(const boost::string_ref& value_name, const t_value& target, hsection hparent_section)
{
TRY_ENTRY();
if(!hparent_section) hparent_section = &m_root;
storage_entry* pentry = find_storage_entry(value_name, hparent_section);
storage_entry* pentry = find_or_create_storage_entry(value_name, hparent_section);
if(!pentry)
{
pentry = insert_new_entry_get_storage_entry(value_name, hparent_section, array_entry(array_entry_t<t_value>()));
if(!pentry)
return nullptr;
}
return nullptr;
if(pentry->type() != typeid(array_entry))
*pentry = storage_entry(array_entry(array_entry_t<t_value>()));

Expand Down Expand Up @@ -403,7 +402,7 @@ namespace epee
//---------------------------------------------------------------------------------------------------------------
//sections
inline
harray portable_storage::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section)
harray portable_storage::get_first_section(const boost::string_ref& sec_name, hsection& h_child_section, hsection hparent_section)
{
TRY_ENTRY();
if(!hparent_section) hparent_section = &m_root;
Expand Down Expand Up @@ -440,17 +439,13 @@ namespace epee
}
//---------------------------------------------------------------------------------------------------------------
inline
harray portable_storage::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section)
harray portable_storage::insert_first_section(const boost::string_ref& sec_name, hsection& hinserted_childsection, hsection hparent_section)
{
TRY_ENTRY();
if(!hparent_section) hparent_section = &m_root;
storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
storage_entry* pentry = find_or_create_storage_entry(sec_name, hparent_section);
if(!pentry)
{
pentry = insert_new_entry_get_storage_entry(sec_name, hparent_section, array_entry(array_entry_t<section>()));
if(!pentry)
return nullptr;
}
return nullptr;
if(pentry->type() != typeid(array_entry))
*pentry = storage_entry(array_entry(array_entry_t<section>()));

Expand Down
14 changes: 7 additions & 7 deletions contrib/epee/include/storages/portable_storage_from_json.h
Expand Up @@ -51,7 +51,7 @@ namespace epee
CHECK_AND_ASSERT_THROW_MES(recursion < EPEE_JSON_RECURSION_LIMIT_INTERNAL, "Wrong JSON data: recursion limitation (" << EPEE_JSON_RECURSION_LIMIT_INTERNAL << ") exceeded");

std::string::const_iterator sub_element_start;
std::string name;
epee::misc_utils::backed_string_ref name;
typename t_storage::harray h_array = nullptr;
enum match_state
{
Expand Down Expand Up @@ -111,10 +111,10 @@ namespace epee
case match_state_wonder_after_separator:
if(*it == '"')
{//just a named string value started
std::string val;
epee::misc_utils::backed_string_ref val;
match_string2(it, buf_end, val);
//insert text value
stg.set_value(name, std::move(val), current_section);
stg.set_value(name, std::move(val.take_string()), current_section);
state = match_state_wonder_after_value;
}else if (epee::misc_utils::parse::isdigit(*it) || *it == '-')
{//just a named number value started
Expand Down Expand Up @@ -201,9 +201,9 @@ namespace epee
}else if(*it == '"')
{
//mean array of strings
std::string val;
epee::misc_utils::backed_string_ref val;
match_string2(it, buf_end, val);
h_array = stg.insert_first_value(name, std::move(val), current_section);
h_array = stg.insert_first_value(name, std::move(val.take_string()), current_section);
CHECK_AND_ASSERT_THROW_MES(h_array, " failed to insert values entry");
state = match_state_array_after_value;
array_md = array_mode_string;
Expand Down Expand Up @@ -289,9 +289,9 @@ namespace epee
case array_mode_string:
if(*it == '"')
{
std::string val;
epee::misc_utils::backed_string_ref val;
match_string2(it, buf_end, val);
bool res = stg.insert_next_value(h_array, std::move(val));
bool res = stg.insert_next_value(h_array, std::move(val.take_string()));
CHECK_AND_ASSERT_THROW_MES(res, "failed to insert values");
state = match_state_array_after_value;
}else CHECK_ISSPACE();
Expand Down

0 comments on commit b831e30

Please sign in to comment.