mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
efficient initialization of vectors-of-vectors-of-vectors
This commit is contained in:
parent
df7b346337
commit
179b4b22ba
3 changed files with 51 additions and 36 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include "zeek/ZeekString.h"
|
#include "zeek/ZeekString.h"
|
||||||
#include "zeek/script_opt/CPP/Attrs.h"
|
#include "zeek/script_opt/CPP/Attrs.h"
|
||||||
#include "zeek/script_opt/CPP/Compile.h"
|
#include "zeek/script_opt/CPP/Compile.h"
|
||||||
|
#include "zeek/script_opt/CPP/RuntimeInits.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -85,25 +86,25 @@ void CPP_InitsInfo::BuildOffsetSet(CPPCompile* c) {
|
||||||
offset_set = c->IndMgr().AddIndices(offsets_vec);
|
offset_set = c->IndMgr().AddIndices(offsets_vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPP_InitsInfo::BuildCohort(CPPCompile* c, std::vector<std::shared_ptr<CPP_InitInfo>>& cohort) {
|
static std::string describe_initializer(const Obj* o) {
|
||||||
int n = 0;
|
auto od = obj_desc(o);
|
||||||
|
|
||||||
|
// Escape any embedded comment characters.
|
||||||
|
od = regex_replace(od, std::regex("/\\*"), "<<SLASH-STAR>>");
|
||||||
|
od = regex_replace(od, std::regex("\\*/"), "<<STAR-SLASH>>");
|
||||||
|
|
||||||
|
return od;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPP_InitsInfo::BuildCohort(CPPCompile* c, std::vector<std::shared_ptr<CPP_InitInfo>>& cohort) {
|
||||||
for ( auto& co : cohort ) {
|
for ( auto& co : cohort ) {
|
||||||
vector<string> ivs;
|
vector<string> ivs;
|
||||||
auto o = co->InitObj();
|
auto o = co->InitObj();
|
||||||
if ( o ) {
|
if ( o )
|
||||||
auto od = obj_desc(o);
|
c->Emit("/* #%s: Initializing %s: */", Fmt(co->Offset()), describe_initializer(o));
|
||||||
|
|
||||||
// Escape any embedded comment characters.
|
|
||||||
od = regex_replace(od, std::regex("/\\*"), "<<SLASH-STAR>>");
|
|
||||||
od = regex_replace(od, std::regex("\\*/"), "<<STAR-SLASH>>");
|
|
||||||
|
|
||||||
c->Emit("/* #%s: Initializing %s: */", Fmt(co->Offset()), od);
|
|
||||||
}
|
|
||||||
|
|
||||||
co->InitializerVals(ivs);
|
co->InitializerVals(ivs);
|
||||||
BuildCohortElement(c, co->InitializerType(), ivs);
|
BuildCohortElement(c, co->InitializerType(), ivs);
|
||||||
++n;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +124,7 @@ void CPP_InitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector<s
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPP_CompoundInitsInfo::GenerateInitializers(CPPCompile* c) {
|
void CPP_CompoundInitsInfo::GenerateInitializers(CPPCompile* c) {
|
||||||
|
c->Emit("");
|
||||||
c->Emit("static int %s_init[] = {", tag);
|
c->Emit("static int %s_init[] = {", tag);
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
|
@ -132,12 +134,25 @@ void CPP_CompoundInitsInfo::GenerateInitializers(CPPCompile* c) {
|
||||||
if ( ++n > 1 )
|
if ( ++n > 1 )
|
||||||
c->Emit("");
|
c->Emit("");
|
||||||
|
|
||||||
c->Emit(Fmt(int(cohort.size())) + ",");
|
// Figure out the size of the cohort.
|
||||||
BuildCohort(c, cohort);
|
for ( auto& co : cohort ) {
|
||||||
c->Emit("-1,");
|
auto o = co->InitObj();
|
||||||
|
if ( o )
|
||||||
|
c->Emit("/* #%s: Initializing %s: */", Fmt(co->Offset()), describe_initializer(o));
|
||||||
|
|
||||||
|
vector<string> ivs;
|
||||||
|
co->InitializerVals(ivs);
|
||||||
|
c->Emit(Fmt(int(ivs.size())) + ",");
|
||||||
|
BuildCohortElement(c, co->InitializerType(), ivs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const auto end_of_vv = Fmt(END_OF_VEC_VEC) + ",";
|
||||||
|
c->Emit(end_of_vv);
|
||||||
}
|
}
|
||||||
|
|
||||||
c->Emit("-2,");
|
static const auto end_of_vvv = Fmt(END_OF_VEC_VEC_VEC) + ",";
|
||||||
|
c->Emit(end_of_vvv);
|
||||||
|
|
||||||
c->IndentDown();
|
c->IndentDown();
|
||||||
c->Emit("};");
|
c->Emit("};");
|
||||||
|
|
||||||
|
@ -149,9 +164,9 @@ void CPP_CompoundInitsInfo::GenerateCohorts(CPPCompile* c) { c->Emit("%s_init",
|
||||||
void CPP_CompoundInitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector<string>& ivs) {
|
void CPP_CompoundInitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector<string>& ivs) {
|
||||||
string init_line;
|
string init_line;
|
||||||
for ( auto& iv : ivs )
|
for ( auto& iv : ivs )
|
||||||
init_line += iv;
|
init_line += iv + ",";
|
||||||
|
|
||||||
c->Emit("%s,", init_line);
|
c->Emit("%s", init_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPP_BasicConstInitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector<string>& ivs) {
|
void CPP_BasicConstInitsInfo::BuildCohortElement(CPPCompile* c, string init_type, vector<string>& ivs) {
|
||||||
|
@ -581,7 +596,8 @@ void IndicesManager::Generate(CPPCompile* c) {
|
||||||
c->Emit(line);
|
c->Emit(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
c->Emit("-1");
|
static const auto end_of_vv = Fmt(END_OF_VEC_VEC);
|
||||||
|
c->Emit(end_of_vv);
|
||||||
c->EndBlock(true);
|
c->EndBlock(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -470,7 +470,7 @@ size_t generate_indices_set(int* inits, std::vector<std::vector<int>>& indices_s
|
||||||
// can pre-allocate the outer vector.
|
// can pre-allocate the outer vector.
|
||||||
auto i_ptr = inits;
|
auto i_ptr = inits;
|
||||||
int num_inits = 0;
|
int num_inits = 0;
|
||||||
while ( *i_ptr >= 0 ) {
|
while ( *i_ptr != END_OF_VEC_VEC && *i_ptr != END_OF_VEC_VEC_VEC ) {
|
||||||
++num_inits;
|
++num_inits;
|
||||||
int n = *i_ptr;
|
int n = *i_ptr;
|
||||||
i_ptr += n + 1; // skip over vector elements
|
i_ptr += n + 1; // skip over vector elements
|
||||||
|
@ -479,7 +479,7 @@ size_t generate_indices_set(int* inits, std::vector<std::vector<int>>& indices_s
|
||||||
indices_set.reserve(num_inits);
|
indices_set.reserve(num_inits);
|
||||||
|
|
||||||
i_ptr = inits;
|
i_ptr = inits;
|
||||||
while ( *i_ptr >= 0 ) {
|
while ( *i_ptr != END_OF_VEC_VEC ) {
|
||||||
int n = *i_ptr;
|
int n = *i_ptr;
|
||||||
++i_ptr;
|
++i_ptr;
|
||||||
std::vector<int> indices;
|
std::vector<int> indices;
|
||||||
|
@ -495,19 +495,13 @@ size_t generate_indices_set(int* inits, std::vector<std::vector<int>>& indices_s
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::vector<std::vector<int>>> generate_indices_set(int* inits) {
|
std::vector<std::vector<std::vector<int>>> generate_indices_set(int* inits) {
|
||||||
// Figure out how many vector-of-vectors there are.
|
std::vector<std::vector<std::vector<int>>> indices_set;
|
||||||
int num_vv = 0;
|
|
||||||
for ( int i = 0; inits[i] >= -1; ++i )
|
|
||||||
if ( inits[i] == -1 )
|
|
||||||
++num_vv;
|
|
||||||
|
|
||||||
std::vector<std::vector<std::vector<int>>> indices_set(num_vv);
|
while ( *inits != END_OF_VEC_VEC_VEC ) {
|
||||||
|
std::vector<std::vector<int>> cohort_inits;
|
||||||
auto i_ptr = inits;
|
inits += generate_indices_set(inits, cohort_inits);
|
||||||
for ( int i = 0; i < num_vv; ++i )
|
indices_set.push_back(std::move(cohort_inits));
|
||||||
i_ptr += generate_indices_set(i_ptr, indices_set[i]);
|
}
|
||||||
|
|
||||||
ASSERT(*i_ptr == -2);
|
|
||||||
|
|
||||||
return indices_set;
|
return indices_set;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,19 +23,24 @@ class InitsManager;
|
||||||
// constructs the corresponding vector-of-vector-of-indices. Each
|
// constructs the corresponding vector-of-vector-of-indices. Each
|
||||||
// vector-of-indices is represented first by an int specifying its
|
// vector-of-indices is represented first by an int specifying its
|
||||||
// size, and then that many int's for its values. We recognize the
|
// size, and then that many int's for its values. We recognize the
|
||||||
// end of the array upon encountering a "size" entry of -1.
|
// end of the array upon encountering a "size" entry of END_OF_VEC_VEC.
|
||||||
//
|
//
|
||||||
// Returns how many elements were processed out of "inits", including its
|
// Returns how many elements were processed out of "inits", including its
|
||||||
// terminator.
|
// terminator.
|
||||||
extern size_t generate_indices_set(int* inits, std::vector<std::vector<int>>& indices_set);
|
extern size_t generate_indices_set(int* inits, std::vector<std::vector<int>>& indices_set);
|
||||||
|
|
||||||
// The same but for one more level of vector construction. The source array
|
// The same but for one more level of vector construction. The source array
|
||||||
// has sub-arrays terminated with -1 per the above, and the whole shebang
|
// has sub-arrays terminated with END_OF_VEC_VEC per the above, and the whole
|
||||||
// is terminated with -2.
|
// shebang is terminated with END_OF_VEC_VEC_VEC.
|
||||||
//
|
//
|
||||||
// Returns the vector construction.
|
// Returns the vector construction.
|
||||||
extern std::vector<std::vector<std::vector<int>>> generate_indices_set(int* inits);
|
extern std::vector<std::vector<std::vector<int>>> generate_indices_set(int* inits);
|
||||||
|
|
||||||
|
// These need to be distinct from any values that can appear, which means
|
||||||
|
// they should be negative, and not -1, which is used as a "N/A" value.
|
||||||
|
#define END_OF_VEC_VEC -100
|
||||||
|
#define END_OF_VEC_VEC_VEC -200
|
||||||
|
|
||||||
// An abstract helper class used to access elements of an initialization vector.
|
// An abstract helper class used to access elements of an initialization vector.
|
||||||
// We need the abstraction because InitsManager below needs to be able to refer
|
// We need the abstraction because InitsManager below needs to be able to refer
|
||||||
// to any of a range of templated classes.
|
// to any of a range of templated classes.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue