mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
added value_footprint() and global_container_footprints() BiFs
This commit is contained in:
parent
02771168f0
commit
16c37034de
5 changed files with 287 additions and 0 deletions
72
src/Val.cc
72
src/Val.cc
|
@ -1322,6 +1322,18 @@ ValPtr ListVal::DoClone(CloneState* state)
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ListVal::Footprint(bool count_entries) const
|
||||||
|
{
|
||||||
|
unsigned int fp = 0;
|
||||||
|
for ( const auto& val : vals )
|
||||||
|
fp += val->Footprint(count_entries);
|
||||||
|
|
||||||
|
if ( count_entries )
|
||||||
|
fp += vals.size();
|
||||||
|
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int ListVal::MemoryAllocation() const
|
unsigned int ListVal::MemoryAllocation() const
|
||||||
{
|
{
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
@ -2673,6 +2685,27 @@ ValPtr TableVal::DoClone(CloneState* state)
|
||||||
return tv;
|
return tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int TableVal::Footprint(bool count_entries) const
|
||||||
|
{
|
||||||
|
unsigned int fp = 0;
|
||||||
|
|
||||||
|
for ( const auto& iter : *table_val )
|
||||||
|
{
|
||||||
|
auto k = iter.GetHashKey();
|
||||||
|
auto vl = table_hash->RecoverVals(*k);
|
||||||
|
auto v = iter.GetValue<TableEntryVal*>()->GetVal();
|
||||||
|
|
||||||
|
fp += vl->Footprint(count_entries);
|
||||||
|
if ( v )
|
||||||
|
fp += v->Footprint(count_entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( count_entries )
|
||||||
|
fp += table_val->Length();
|
||||||
|
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int TableVal::MemoryAllocation() const
|
unsigned int TableVal::MemoryAllocation() const
|
||||||
{
|
{
|
||||||
unsigned int size = 0;
|
unsigned int size = 0;
|
||||||
|
@ -3038,6 +3071,27 @@ ValPtr RecordVal::DoClone(CloneState* state)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int RecordVal::Footprint(bool count_entries) const
|
||||||
|
{
|
||||||
|
unsigned int fp = 0;
|
||||||
|
int n = NumFields();
|
||||||
|
|
||||||
|
for ( auto i = 0; i < n; ++i )
|
||||||
|
{
|
||||||
|
if ( ! HasField(i) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto f_i = GetField(i);
|
||||||
|
if ( f_i )
|
||||||
|
fp += f_i->Footprint(count_entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( count_entries )
|
||||||
|
fp += n;
|
||||||
|
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int RecordVal::MemoryAllocation() const
|
unsigned int RecordVal::MemoryAllocation() const
|
||||||
{
|
{
|
||||||
unsigned int size = 0;
|
unsigned int size = 0;
|
||||||
|
@ -3561,6 +3615,24 @@ bool VectorVal::Concretize(const TypePtr& t)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int VectorVal::Footprint(bool count_entries) const
|
||||||
|
{
|
||||||
|
unsigned int fp = 0;
|
||||||
|
auto n = vector_val->size();
|
||||||
|
|
||||||
|
for ( auto i = 0U; i < n; ++i )
|
||||||
|
{
|
||||||
|
auto v = At(i);
|
||||||
|
if ( v )
|
||||||
|
fp += v->Footprint(count_entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( count_entries )
|
||||||
|
fp += n;
|
||||||
|
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int VectorVal::Resize(unsigned int new_num_elements)
|
unsigned int VectorVal::Resize(unsigned int new_num_elements)
|
||||||
{
|
{
|
||||||
unsigned int oldsize = vector_val->size();
|
unsigned int oldsize = vector_val->size();
|
||||||
|
|
20
src/Val.h
20
src/Val.h
|
@ -121,6 +121,18 @@ public:
|
||||||
// size depends on the Val's type.
|
// size depends on the Val's type.
|
||||||
virtual ValPtr SizeVal() const;
|
virtual ValPtr SizeVal() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Val's "footprint", i.e., how many atomic (non-container)
|
||||||
|
* values it includes, either directly or indirectly.
|
||||||
|
*
|
||||||
|
* @param count_entries If true, (recursively) include in the
|
||||||
|
* footprint the count of the number of container elements as well
|
||||||
|
* as each element's footprint.
|
||||||
|
*
|
||||||
|
* @return The total footprint, optionally including element counts.
|
||||||
|
*/
|
||||||
|
virtual unsigned int Footprint(bool count_entries) const { return 1; }
|
||||||
|
|
||||||
// Bytes in total value object.
|
// Bytes in total value object.
|
||||||
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
||||||
"GHI-572.")]] virtual unsigned int
|
"GHI-572.")]] virtual unsigned int
|
||||||
|
@ -666,6 +678,8 @@ public:
|
||||||
|
|
||||||
void Describe(ODesc* d) const override;
|
void Describe(ODesc* d) const override;
|
||||||
|
|
||||||
|
unsigned int Footprint(bool count_entries) const override;
|
||||||
|
|
||||||
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
||||||
"GHI-572.")]] unsigned int
|
"GHI-572.")]] unsigned int
|
||||||
MemoryAllocation() const override;
|
MemoryAllocation() const override;
|
||||||
|
@ -941,6 +955,8 @@ public:
|
||||||
// the function in the frame allowing it to capture its closure.
|
// the function in the frame allowing it to capture its closure.
|
||||||
void InitDefaultFunc(detail::Frame* f);
|
void InitDefaultFunc(detail::Frame* f);
|
||||||
|
|
||||||
|
unsigned int Footprint(bool count_entries) const override;
|
||||||
|
|
||||||
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
||||||
"GHI-572.")]] unsigned int
|
"GHI-572.")]] unsigned int
|
||||||
MemoryAllocation() const override;
|
MemoryAllocation() const override;
|
||||||
|
@ -1367,6 +1383,8 @@ public:
|
||||||
}
|
}
|
||||||
RecordValPtr CoerceTo(RecordTypePtr other, bool allow_orphaning = false);
|
RecordValPtr CoerceTo(RecordTypePtr other, bool allow_orphaning = false);
|
||||||
|
|
||||||
|
unsigned int Footprint(bool count_entries) const override;
|
||||||
|
|
||||||
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
[[deprecated("Remove in v5.1. MemoryAllocation() is deprecated and will be removed. See "
|
||||||
"GHI-572.")]] unsigned int
|
"GHI-572.")]] unsigned int
|
||||||
MemoryAllocation() const override;
|
MemoryAllocation() const override;
|
||||||
|
@ -1624,6 +1642,8 @@ public:
|
||||||
const auto& RawYieldType() const { return yield_type; }
|
const auto& RawYieldType() const { return yield_type; }
|
||||||
const auto& RawYieldTypes() const { return yield_types; }
|
const auto& RawYieldTypes() const { return yield_types; }
|
||||||
|
|
||||||
|
unsigned int Footprint(bool count_entries) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Returns the element at a given index or nullptr if it does not exist.
|
* Returns the element at a given index or nullptr if it does not exist.
|
||||||
|
|
43
src/zeek.bif
43
src/zeek.bif
|
@ -1985,6 +1985,49 @@ function global_sizes%(%): var_sizes &deprecated="Remove in v5.1. MemoryAllocati
|
||||||
return sizes;
|
return sizes;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
## Generates a table of the footprint of all global container variables.
|
||||||
|
## The table index is the variable name and the value is the footprint.
|
||||||
|
## The argument specifies whether the footprint should (recursively) include
|
||||||
|
## the number of entries in each global.
|
||||||
|
##
|
||||||
|
## Returns: A table that maps variable names to their footprints.
|
||||||
|
##
|
||||||
|
## .. zeek:see:: value_footprint
|
||||||
|
function global_container_footprints%(count_entries: bool%): var_sizes
|
||||||
|
%{
|
||||||
|
auto sizes = zeek::make_intrusive<zeek::TableVal>(IntrusivePtr{zeek::NewRef{}, var_sizes});
|
||||||
|
const auto& globals = zeek::detail::global_scope()->Vars();
|
||||||
|
|
||||||
|
for ( const auto& global : globals )
|
||||||
|
{
|
||||||
|
auto& id = global.second;
|
||||||
|
auto v = id->GetVal();
|
||||||
|
|
||||||
|
if ( ! v || ! IsAggr(v->GetType()) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto id_name = zeek::make_intrusive<zeek::StringVal>(id->Name());
|
||||||
|
auto fp = zeek::val_mgr->Count(v->Footprint(count_entries));
|
||||||
|
sizes->Assign(std::move(id_name), std::move(fp));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sizes;
|
||||||
|
%}
|
||||||
|
|
||||||
|
## Computes a value's "footprint" (number of atomic elements included, either
|
||||||
|
## directly or indirectly). The argument, if true, specifies that the
|
||||||
|
## footprint should also include the number of entries in each included
|
||||||
|
## container.
|
||||||
|
##
|
||||||
|
## Returns: the total number of atomic elements plus (optionally) the
|
||||||
|
## number of entries in included containers.
|
||||||
|
##
|
||||||
|
## .. zeek:see:: global_container_footprints
|
||||||
|
function value_footprint%(v: any, count_entries: bool%): count
|
||||||
|
%{
|
||||||
|
return zeek::val_mgr->Count(v->Footprint(count_entries));
|
||||||
|
%}
|
||||||
|
|
||||||
## Generates a table with information about all global identifiers. The table
|
## Generates a table with information about all global identifiers. The table
|
||||||
## value is a record containing the type name of the identifier, whether it is
|
## value is a record containing the type name of the identifier, whether it is
|
||||||
## exported, a constant, an enum constant, redefinable, and its value (if it
|
## exported, a constant, an enum constant, redefinable, and its value (if it
|
||||||
|
|
49
testing/btest/Baseline/bifs.footprint/out
Normal file
49
testing/btest/Baseline/bifs.footprint/out
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||||
|
bool, 1
|
||||||
|
bool, 1
|
||||||
|
count, 1
|
||||||
|
count, 1
|
||||||
|
int, 1
|
||||||
|
int, 1
|
||||||
|
double, 1
|
||||||
|
double, 1
|
||||||
|
string, 1
|
||||||
|
string, 1
|
||||||
|
pattern, 1
|
||||||
|
pattern, 1
|
||||||
|
addr, 1
|
||||||
|
addr, 1
|
||||||
|
subnet, 1
|
||||||
|
subnet, 1
|
||||||
|
port, 1
|
||||||
|
port, 1
|
||||||
|
l1, 0
|
||||||
|
l1, 3
|
||||||
|
l1b, 3
|
||||||
|
l1b, 6
|
||||||
|
l2, 2
|
||||||
|
l2, 7
|
||||||
|
l2b, 4
|
||||||
|
l2b, 9
|
||||||
|
v1, 4
|
||||||
|
v1, 8
|
||||||
|
v2, 8
|
||||||
|
v2, 18
|
||||||
|
v3, 3
|
||||||
|
v3, 11
|
||||||
|
t1, 6
|
||||||
|
t1, 12
|
||||||
|
t2, 9
|
||||||
|
t2, 18
|
||||||
|
t3, 20
|
||||||
|
t3, 46
|
||||||
|
t4, 7
|
||||||
|
t4, 19
|
||||||
|
s1, 3
|
||||||
|
s1, 9
|
||||||
|
s2, 6
|
||||||
|
s2, 15
|
||||||
|
s3, 8
|
||||||
|
s3, 20
|
||||||
|
s4, 3
|
||||||
|
s4, 9
|
103
testing/btest/bifs/footprint.zeek
Normal file
103
testing/btest/bifs/footprint.zeek
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
# @TEST-EXEC: zeek -b %INPUT >out
|
||||||
|
# @TEST-EXEC: btest-diff out
|
||||||
|
|
||||||
|
type r1: record {
|
||||||
|
a: count;
|
||||||
|
b: double;
|
||||||
|
c: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type r2: record {
|
||||||
|
a: count;
|
||||||
|
b1: double &default = 1.0;
|
||||||
|
b2: double &default = 2.0;
|
||||||
|
c: string &optional;
|
||||||
|
d: string &optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
event zeek_init()
|
||||||
|
{
|
||||||
|
print "bool", value_footprint(T, F);
|
||||||
|
print "bool", value_footprint(T, T);
|
||||||
|
print "count", value_footprint(3, F);
|
||||||
|
print "count", value_footprint(4, T);
|
||||||
|
print "int", value_footprint(-3, F);
|
||||||
|
print "int", value_footprint(-4, T);
|
||||||
|
print "double", value_footprint(-3.0, F);
|
||||||
|
print "double", value_footprint(4e99, T);
|
||||||
|
print "string", value_footprint("short", F);
|
||||||
|
print "string", value_footprint("longlonglong", T);
|
||||||
|
print "pattern", value_footprint(/short/, F);
|
||||||
|
print "pattern", value_footprint(/longlonglong/, T);
|
||||||
|
print "addr", value_footprint(1.2.3.4, F);
|
||||||
|
print "addr", value_footprint([ffff::ffff], T);
|
||||||
|
print "subnet", value_footprint(1.2.3.4/22, F);
|
||||||
|
print "subnet", value_footprint([ffff::ffff]/99, T);
|
||||||
|
print "port", value_footprint(123/tcp, F);
|
||||||
|
print "port", value_footprint(9999/udp, T);
|
||||||
|
|
||||||
|
local l1: r1;
|
||||||
|
print "l1", value_footprint(l1, F);
|
||||||
|
print "l1", value_footprint(l1, T);
|
||||||
|
|
||||||
|
local l1b = r1($a=3, $b=3.0, $c="3");
|
||||||
|
print "l1b", value_footprint(l1b, F);
|
||||||
|
print "l1b", value_footprint(l1b, T);
|
||||||
|
|
||||||
|
local l2: r2;
|
||||||
|
print "l2", value_footprint(l2, F);
|
||||||
|
print "l2", value_footprint(l2, T);
|
||||||
|
|
||||||
|
local l2b = r2($a=3, $b1=99.0, $c="I'm here");
|
||||||
|
print "l2b", value_footprint(l2b, F);
|
||||||
|
print "l2b", value_footprint(l2b, T);
|
||||||
|
|
||||||
|
local v1 = vector(9, 7, 3, 1);
|
||||||
|
print "v1", value_footprint(v1, F);
|
||||||
|
print "v1", value_footprint(v1, T);
|
||||||
|
|
||||||
|
local v2 = vector(v1, v1);
|
||||||
|
print "v2", value_footprint(v2, F);
|
||||||
|
print "v2", value_footprint(v2, T);
|
||||||
|
|
||||||
|
local v3 = vector(l1, l1b);
|
||||||
|
print "v3", value_footprint(v3, F);
|
||||||
|
print "v3", value_footprint(v3, T);
|
||||||
|
|
||||||
|
local t1 = table([1] = 1, [2] = 4, [3] = 9);
|
||||||
|
print "t1", value_footprint(t1, F);
|
||||||
|
# Note, table and set footprint values using count_entries=T because
|
||||||
|
# table indices are ListVal's, so those add their own container
|
||||||
|
# entry counts into the sum.
|
||||||
|
print "t1", value_footprint(t1, T);
|
||||||
|
|
||||||
|
local t2 = table([1, 3] = 1, [2, 3] = 4, [3, 3] = 9);
|
||||||
|
print "t2", value_footprint(t2, F);
|
||||||
|
print "t2", value_footprint(t2, T);
|
||||||
|
|
||||||
|
local t3 = table([1, 3] = v2, [2, 3] = v2);
|
||||||
|
print "t3", value_footprint(t3, F);
|
||||||
|
print "t3", value_footprint(t3, T);
|
||||||
|
|
||||||
|
local t4 = table([1, 3] = l1, [2, 3] = l1b);
|
||||||
|
print "t4", value_footprint(t4, F);
|
||||||
|
print "t4", value_footprint(t4, T);
|
||||||
|
|
||||||
|
local s1 = set(1, 4, 9);
|
||||||
|
print "s1", value_footprint(s1, F);
|
||||||
|
print "s1", value_footprint(s1, T);
|
||||||
|
|
||||||
|
local s2 = set([1, 3], [2, 3], [3, 3]);
|
||||||
|
print "s2", value_footprint(s2, F);
|
||||||
|
print "s2", value_footprint(s2, T);
|
||||||
|
|
||||||
|
local s3: set[r1, count];
|
||||||
|
add s3[l1b, 9];
|
||||||
|
add s3[l1b, 12];
|
||||||
|
print "s3", value_footprint(s3, F);
|
||||||
|
print "s3", value_footprint(s3, T);
|
||||||
|
|
||||||
|
local s4 = set(vector(l1b), vector(l1b), vector(l1b));
|
||||||
|
print "s4", value_footprint(s4, F);
|
||||||
|
print "s4", value_footprint(s4, T);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue