mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-30 03:34:29 +03:00
Improve performance of VariableOrigin instances
- The previous approach would create a std::unique_ptr and store it in a std::list in VariableValue (Origins) - The new approach now stores Origins in a std::vector and constructs VariableOrigin elements in-place on insertion. - Instead of having two heap-allocations for every added VariableOrigin instance, this performs only one. - If multiple origins are added, std::vector's growth strategy may even prevent a heap-allocation. There's a cost on growing the size of the vector, because a copy of current elements will be necessary. - Introduced reserveOrigin method to notify that multiple insertions will be made, so that we can use std::vector's reserve and do a single allocation (and copy of previous elements), and then just initialize the new elements in-place.
This commit is contained in:
@@ -47,11 +47,12 @@ class AnchoredSetVariableTranslationProxy {
|
||||
VariableValue *newVariableValue = new VariableValue(name, &l->at(i)->getKey(), &l->at(i)->getKey());
|
||||
const VariableValue *oldVariableValue = l->at(i);
|
||||
l->at(i) = newVariableValue;
|
||||
newVariableValue->reserveOrigin(oldVariableValue->getOrigin().size());
|
||||
for (const auto &oldOrigin : oldVariableValue->getOrigin()) {
|
||||
std::unique_ptr<VariableOrigin> newOrigin(new VariableOrigin);
|
||||
newOrigin->m_length = oldVariableValue->getKey().size();
|
||||
newOrigin->m_offset = oldOrigin->m_offset - oldVariableValue->getKey().size() - 1;
|
||||
newVariableValue->addOrigin(std::move(newOrigin));
|
||||
newVariableValue->addOrigin(
|
||||
oldVariableValue->getKey().size(),
|
||||
oldOrigin.m_offset - oldVariableValue->getKey().size() - 1
|
||||
);
|
||||
}
|
||||
delete oldVariableValue;
|
||||
}
|
||||
|
@@ -63,7 +63,7 @@ class AnchoredVariable {
|
||||
void append(const std::string &a, size_t offset,
|
||||
bool spaceSeparator = false);
|
||||
void append(const std::string &a, size_t offset,
|
||||
bool spaceSeparator, int size);
|
||||
bool spaceSeparator, size_t size);
|
||||
|
||||
void evaluate(std::vector<const VariableValue *> *l);
|
||||
std::string * evaluate();
|
||||
|
@@ -15,6 +15,7 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
#ifndef HEADERS_MODSECURITY_VARIABLE_ORIGIN_H_
|
||||
@@ -36,14 +37,17 @@ class VariableOrigin {
|
||||
VariableOrigin()
|
||||
: m_length(0),
|
||||
m_offset(0) { }
|
||||
VariableOrigin(size_t length, size_t offset)
|
||||
: m_length(length),
|
||||
m_offset(offset) { }
|
||||
|
||||
std::string toText() {
|
||||
std::string offset = std::to_string(m_offset);
|
||||
std::string len = std::to_string(m_length);
|
||||
std::string toText() const {
|
||||
const auto offset = std::to_string(m_offset);
|
||||
const auto len = std::to_string(m_length);
|
||||
return "v" + offset + "," + len;
|
||||
}
|
||||
|
||||
int m_length;
|
||||
size_t m_length;
|
||||
size_t m_offset;
|
||||
};
|
||||
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace modsecurity {
|
||||
class Collection;
|
||||
class VariableValue {
|
||||
public:
|
||||
using Origins = std::list<std::unique_ptr<VariableOrigin>>;
|
||||
using Origins = std::vector<VariableOrigin>;
|
||||
|
||||
explicit VariableValue(const std::string *key,
|
||||
const std::string *value = nullptr)
|
||||
@@ -62,11 +62,9 @@ class VariableValue {
|
||||
m_keyWithCollection(o->m_keyWithCollection),
|
||||
m_value(o->m_value)
|
||||
{
|
||||
reserveOrigin(o->m_orign.size());
|
||||
for (const auto &i : o->m_orign) {
|
||||
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
|
||||
origin->m_offset = i->m_offset;
|
||||
origin->m_length = i->m_length;
|
||||
m_orign.push_back(std::move(origin));
|
||||
addOrigin(i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,8 +96,14 @@ class VariableValue {
|
||||
}
|
||||
|
||||
|
||||
void addOrigin(std::unique_ptr<VariableOrigin> origin) {
|
||||
m_orign.push_back(std::move(origin));
|
||||
void addOrigin(const VariableOrigin &origin) {
|
||||
m_orign.emplace_back(origin);
|
||||
}
|
||||
|
||||
|
||||
template<typename... Args>
|
||||
void addOrigin(Args&&... args) {
|
||||
m_orign.emplace_back(args...);
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +111,12 @@ class VariableValue {
|
||||
return m_orign;
|
||||
}
|
||||
|
||||
|
||||
void reserveOrigin(Origins::size_type additionalSize) {
|
||||
m_orign.reserve(m_orign.size() + additionalSize);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Origins m_orign;
|
||||
std::string m_collection;
|
||||
|
Reference in New Issue
Block a user