mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
RecordVal: Embed record_val
This should remove one malloc/free per created and destroyed record instance and avoid one extra pointer indirection to access fields.
This commit is contained in:
parent
32944ebc5d
commit
f362935a66
2 changed files with 42 additions and 44 deletions
22
src/Val.cc
22
src/Val.cc
|
@ -3155,17 +3155,15 @@ RecordVal::RecordVal(RecordTypePtr t, bool init_fields) : Val(t), is_managed(t->
|
|||
if ( run_state::is_parsing )
|
||||
parse_time_records[rt.get()].emplace_back(NewRef{}, this);
|
||||
|
||||
record_val = new std::vector<std::optional<ZVal>>;
|
||||
|
||||
if ( init_fields )
|
||||
{
|
||||
record_val->resize(n);
|
||||
record_val.resize(n);
|
||||
|
||||
for ( auto& e : rt->CreationInits() )
|
||||
{
|
||||
try
|
||||
{
|
||||
(*record_val)[e.first] = e.second->Generate();
|
||||
record_val[e.first] = e.second->Generate();
|
||||
}
|
||||
catch ( InterpreterException& e )
|
||||
{
|
||||
|
@ -3177,21 +3175,19 @@ RecordVal::RecordVal(RecordTypePtr t, bool init_fields) : Val(t), is_managed(t->
|
|||
}
|
||||
|
||||
else
|
||||
record_val->reserve(n);
|
||||
record_val.reserve(n);
|
||||
}
|
||||
|
||||
RecordVal::~RecordVal()
|
||||
{
|
||||
auto n = record_val->size();
|
||||
auto n = record_val.size();
|
||||
|
||||
for ( unsigned int i = 0; i < n; ++i )
|
||||
{
|
||||
auto f_i = (*record_val)[i];
|
||||
auto f_i = record_val[i];
|
||||
if ( f_i && IsManaged(i) )
|
||||
ZVal::DeleteManagedType(*f_i);
|
||||
}
|
||||
|
||||
delete record_val;
|
||||
}
|
||||
|
||||
ValPtr RecordVal::SizeVal() const
|
||||
|
@ -3206,7 +3202,7 @@ void RecordVal::Assign(int field, ValPtr new_val)
|
|||
DeleteFieldIfManaged(field);
|
||||
|
||||
auto t = rt->GetFieldType(field);
|
||||
(*record_val)[field] = ZVal(new_val, t);
|
||||
record_val[field] = ZVal(new_val, t);
|
||||
Modified();
|
||||
}
|
||||
else
|
||||
|
@ -3215,7 +3211,7 @@ void RecordVal::Assign(int field, ValPtr new_val)
|
|||
|
||||
void RecordVal::Remove(int field)
|
||||
{
|
||||
auto& f_i = (*record_val)[field];
|
||||
auto& f_i = record_val[field];
|
||||
if ( f_i )
|
||||
{
|
||||
if ( IsManaged(field) )
|
||||
|
@ -3357,7 +3353,7 @@ TableValPtr RecordVal::GetRecordFieldsVal() const
|
|||
|
||||
void RecordVal::Describe(ODesc* d) const
|
||||
{
|
||||
auto n = record_val->size();
|
||||
auto n = record_val.size();
|
||||
|
||||
if ( d->IsBinary() )
|
||||
{
|
||||
|
@ -3393,7 +3389,7 @@ void RecordVal::Describe(ODesc* d) const
|
|||
|
||||
void RecordVal::DescribeReST(ODesc* d) const
|
||||
{
|
||||
auto n = record_val->size();
|
||||
auto n = record_val.size();
|
||||
auto rt = GetType()->AsRecordType();
|
||||
|
||||
d->Add("{");
|
||||
|
|
64
src/Val.h
64
src/Val.h
|
@ -1154,7 +1154,7 @@ public:
|
|||
// The following provide efficient record field assignments.
|
||||
void Assign(int field, bool new_val)
|
||||
{
|
||||
(*record_val)[field] = ZVal(zeek_int_t(new_val));
|
||||
record_val[field] = ZVal(zeek_int_t(new_val));
|
||||
AddedField(field);
|
||||
}
|
||||
|
||||
|
@ -1162,28 +1162,28 @@ public:
|
|||
// convenience, since sometimes the caller has one rather than the other.
|
||||
void Assign(int field, int32_t new_val)
|
||||
{
|
||||
(*record_val)[field] = ZVal(zeek_int_t(new_val));
|
||||
record_val[field] = ZVal(zeek_int_t(new_val));
|
||||
AddedField(field);
|
||||
}
|
||||
void Assign(int field, int64_t new_val)
|
||||
{
|
||||
(*record_val)[field] = ZVal(zeek_int_t(new_val));
|
||||
record_val[field] = ZVal(zeek_int_t(new_val));
|
||||
AddedField(field);
|
||||
}
|
||||
void Assign(int field, uint32_t new_val)
|
||||
{
|
||||
(*record_val)[field] = ZVal(zeek_uint_t(new_val));
|
||||
record_val[field] = ZVal(zeek_uint_t(new_val));
|
||||
AddedField(field);
|
||||
}
|
||||
void Assign(int field, uint64_t new_val)
|
||||
{
|
||||
(*record_val)[field] = ZVal(zeek_uint_t(new_val));
|
||||
record_val[field] = ZVal(zeek_uint_t(new_val));
|
||||
AddedField(field);
|
||||
}
|
||||
|
||||
void Assign(int field, double new_val)
|
||||
{
|
||||
(*record_val)[field] = ZVal(new_val);
|
||||
record_val[field] = ZVal(new_val);
|
||||
AddedField(field);
|
||||
}
|
||||
|
||||
|
@ -1196,7 +1196,7 @@ public:
|
|||
|
||||
void Assign(int field, StringVal* new_val)
|
||||
{
|
||||
auto& fv = (*record_val)[field];
|
||||
auto& fv = record_val[field];
|
||||
if ( fv )
|
||||
ZVal::DeleteManagedType(*fv);
|
||||
fv = ZVal(new_val);
|
||||
|
@ -1222,7 +1222,7 @@ public:
|
|||
* Returns the number of fields in the record.
|
||||
* @return The number of fields in the record.
|
||||
*/
|
||||
unsigned int NumFields() const { return record_val->size(); }
|
||||
unsigned int NumFields() const { return record_val.size(); }
|
||||
|
||||
/**
|
||||
* Returns true if the given field is in the record, false if
|
||||
|
@ -1232,7 +1232,7 @@ public:
|
|||
*/
|
||||
bool HasField(int field) const
|
||||
{
|
||||
if ( (*record_val)[field] )
|
||||
if ( record_val[field] )
|
||||
return true;
|
||||
|
||||
return rt->DeferredInits()[field] != nullptr;
|
||||
|
@ -1257,7 +1257,7 @@ public:
|
|||
*/
|
||||
ValPtr GetField(int field) const
|
||||
{
|
||||
auto& fv = (*record_val)[field];
|
||||
auto& fv = record_val[field];
|
||||
if ( ! fv )
|
||||
{
|
||||
const auto& fi = rt->DeferredInits()[field];
|
||||
|
@ -1342,32 +1342,32 @@ public:
|
|||
{
|
||||
if constexpr ( std::is_same_v<T, BoolVal> || std::is_same_v<T, IntVal> ||
|
||||
std::is_same_v<T, EnumVal> )
|
||||
return record_val->operator[](field)->int_val;
|
||||
return record_val[field]->int_val;
|
||||
else if constexpr ( std::is_same_v<T, CountVal> )
|
||||
return record_val->operator[](field)->uint_val;
|
||||
return record_val[field]->uint_val;
|
||||
else if constexpr ( std::is_same_v<T, DoubleVal> || std::is_same_v<T, TimeVal> ||
|
||||
std::is_same_v<T, IntervalVal> )
|
||||
return record_val->operator[](field)->double_val;
|
||||
return record_val[field]->double_val;
|
||||
else if constexpr ( std::is_same_v<T, PortVal> )
|
||||
return val_mgr->Port(record_val->at(field)->uint_val);
|
||||
return val_mgr->Port(record_val[field]->uint_val);
|
||||
else if constexpr ( std::is_same_v<T, StringVal> )
|
||||
return record_val->operator[](field)->string_val->Get();
|
||||
return record_val[field]->string_val->Get();
|
||||
else if constexpr ( std::is_same_v<T, AddrVal> )
|
||||
return record_val->operator[](field)->addr_val->Get();
|
||||
return record_val[field]->addr_val->Get();
|
||||
else if constexpr ( std::is_same_v<T, SubNetVal> )
|
||||
return record_val->operator[](field)->subnet_val->Get();
|
||||
return record_val[field]->subnet_val->Get();
|
||||
else if constexpr ( std::is_same_v<T, File> )
|
||||
return *(record_val->operator[](field)->file_val);
|
||||
return *(record_val[field]->file_val);
|
||||
else if constexpr ( std::is_same_v<T, Func> )
|
||||
return *(record_val->operator[](field)->func_val);
|
||||
return *(record_val[field]->func_val);
|
||||
else if constexpr ( std::is_same_v<T, PatternVal> )
|
||||
return record_val->operator[](field)->re_val->Get();
|
||||
return record_val[field]->re_val->Get();
|
||||
else if constexpr ( std::is_same_v<T, RecordVal> )
|
||||
return record_val->operator[](field)->record_val;
|
||||
return record_val[field]->record_val;
|
||||
else if constexpr ( std::is_same_v<T, VectorVal> )
|
||||
return record_val->operator[](field)->vector_val;
|
||||
return record_val[field]->vector_val;
|
||||
else if constexpr ( std::is_same_v<T, TableVal> )
|
||||
return record_val->operator[](field)->table_val->Get();
|
||||
return record_val[field]->table_val->Get();
|
||||
else
|
||||
{
|
||||
// It's an error to reach here, although because of
|
||||
|
@ -1381,11 +1381,11 @@ public:
|
|||
T GetFieldAs(int field) const
|
||||
{
|
||||
if constexpr ( std::is_integral_v<T> && std::is_signed_v<T> )
|
||||
return record_val->operator[](field)->int_val;
|
||||
return record_val[field]->int_val;
|
||||
else if constexpr ( std::is_integral_v<T> && std::is_unsigned_v<T> )
|
||||
return record_val->operator[](field)->uint_val;
|
||||
return record_val[field]->uint_val;
|
||||
else if constexpr ( std::is_floating_point_v<T> )
|
||||
return record_val->operator[](field)->double_val;
|
||||
return record_val[field]->double_val;
|
||||
|
||||
// Note: we could add other types here using type traits,
|
||||
// such as is_same_v<T, std::string>, etc.
|
||||
|
@ -1460,9 +1460,9 @@ protected:
|
|||
void AppendField(ValPtr v, const TypePtr& t)
|
||||
{
|
||||
if ( v )
|
||||
record_val->emplace_back(ZVal(v, t));
|
||||
record_val.emplace_back(ZVal(v, t));
|
||||
else
|
||||
record_val->emplace_back(std::nullopt);
|
||||
record_val.emplace_back(std::nullopt);
|
||||
}
|
||||
|
||||
// For internal use by low-level ZAM instructions and event tracing.
|
||||
|
@ -1471,7 +1471,7 @@ protected:
|
|||
// The second version ensures that the optional value is present.
|
||||
std::optional<ZVal>& RawOptField(int field)
|
||||
{
|
||||
auto& f = (*record_val)[field];
|
||||
auto& f = record_val[field];
|
||||
if ( ! f )
|
||||
{
|
||||
const auto& fi = rt->DeferredInits()[field];
|
||||
|
@ -1502,7 +1502,7 @@ protected:
|
|||
private:
|
||||
void DeleteFieldIfManaged(unsigned int field)
|
||||
{
|
||||
auto& f = (*record_val)[field];
|
||||
auto& f = record_val[field];
|
||||
if ( f && IsManaged(field) )
|
||||
ZVal::DeleteManagedType(*f);
|
||||
}
|
||||
|
@ -1518,7 +1518,9 @@ private:
|
|||
RecordTypePtr rt;
|
||||
|
||||
// Low-level values of each of the fields.
|
||||
std::vector<std::optional<ZVal>>* record_val;
|
||||
//
|
||||
// Lazily modified during GetField(), so mutable.
|
||||
mutable std::vector<std::optional<ZVal>> record_val;
|
||||
|
||||
// Whether a given field requires explicit memory management.
|
||||
const std::vector<bool>& is_managed;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue