mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
streamlining of constructing script-level tables
This commit is contained in:
parent
d1d9b9a1be
commit
a11ee9038b
4 changed files with 52 additions and 27 deletions
11
src/Type.cc
11
src/Type.cc
|
@ -10,6 +10,7 @@
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "zeek/Attr.h"
|
#include "zeek/Attr.h"
|
||||||
|
#include "zeek/CompHash.h"
|
||||||
#include "zeek/Desc.h"
|
#include "zeek/Desc.h"
|
||||||
#include "zeek/Expr.h"
|
#include "zeek/Expr.h"
|
||||||
#include "zeek/Reporter.h"
|
#include "zeek/Reporter.h"
|
||||||
|
@ -478,8 +479,13 @@ TableType::TableType(TypeListPtr ind, TypePtr yield) : IndexType(TYPE_TABLE, std
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( Tag() != TYPE_ERROR )
|
||||||
|
RegenerateHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TableType::~TableType() { delete table_hash; }
|
||||||
|
|
||||||
bool TableType::CheckExpireFuncCompatibility(const detail::AttrPtr& attr) {
|
bool TableType::CheckExpireFuncCompatibility(const detail::AttrPtr& attr) {
|
||||||
if ( reported_error )
|
if ( reported_error )
|
||||||
return false;
|
return false;
|
||||||
|
@ -493,6 +499,11 @@ bool TableType::CheckExpireFuncCompatibility(const detail::AttrPtr& attr) {
|
||||||
|
|
||||||
TypePtr TableType::ShallowClone() { return make_intrusive<TableType>(indices, yield_type); }
|
TypePtr TableType::ShallowClone() { return make_intrusive<TableType>(indices, yield_type); }
|
||||||
|
|
||||||
|
void TableType::RegenerateHash() {
|
||||||
|
delete table_hash;
|
||||||
|
table_hash = new detail::CompositeHash(GetIndices());
|
||||||
|
}
|
||||||
|
|
||||||
bool TableType::IsUnspecifiedTable() const {
|
bool TableType::IsUnspecifiedTable() const {
|
||||||
// Unspecified types have an empty list of indices.
|
// Unspecified types have an empty list of indices.
|
||||||
return indices->GetTypes().empty();
|
return indices->GetTypes().empty();
|
||||||
|
|
30
src/Type.h
30
src/Type.h
|
@ -29,6 +29,7 @@ using TableValPtr = IntrusivePtr<TableVal>;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
class CompositeHash;
|
||||||
class Expr;
|
class Expr;
|
||||||
class ListExpr;
|
class ListExpr;
|
||||||
class Attributes;
|
class Attributes;
|
||||||
|
@ -354,22 +355,20 @@ public:
|
||||||
void DescribeReST(ODesc* d, bool roles_only = false) const override;
|
void DescribeReST(ODesc* d, bool roles_only = false) const override;
|
||||||
|
|
||||||
// Returns true if this table is solely indexed by subnet.
|
// Returns true if this table is solely indexed by subnet.
|
||||||
bool IsSubNetIndex() const {
|
bool IsSubNetIndex() const { return is_subnet_index; }
|
||||||
const auto& types = indices->GetTypes();
|
|
||||||
return types.size() == 1 && types[0]->Tag() == TYPE_SUBNET;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if this table has a single index of type pattern.
|
// Returns true if this table has a single index of type pattern.
|
||||||
bool IsPatternIndex() const {
|
bool IsPatternIndex() const { return is_pattern_index; }
|
||||||
const auto& types = indices->GetTypes();
|
|
||||||
return types.size() == 1 && types[0]->Tag() == TYPE_PATTERN;
|
|
||||||
}
|
|
||||||
|
|
||||||
detail::TraversalCode Traverse(detail::TraversalCallback* cb) const override;
|
detail::TraversalCode Traverse(detail::TraversalCallback* cb) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
IndexType(TypeTag t, TypeListPtr arg_indices, TypePtr arg_yield_type)
|
IndexType(TypeTag t, TypeListPtr arg_indices, TypePtr arg_yield_type)
|
||||||
: Type(t), indices(std::move(arg_indices)), yield_type(std::move(arg_yield_type)) {}
|
: Type(t), indices(std::move(arg_indices)), yield_type(std::move(arg_yield_type)) {
|
||||||
|
const auto& types = indices->GetTypes();
|
||||||
|
is_subnet_index = types.size() == 1 && types[0]->Tag() == TYPE_SUBNET;
|
||||||
|
is_pattern_index = types.size() == 1 && types[0]->Tag() == TYPE_PATTERN;
|
||||||
|
}
|
||||||
|
|
||||||
~IndexType() override = default;
|
~IndexType() override = default;
|
||||||
|
|
||||||
|
@ -377,12 +376,17 @@ protected:
|
||||||
|
|
||||||
TypeListPtr indices;
|
TypeListPtr indices;
|
||||||
TypePtr yield_type;
|
TypePtr yield_type;
|
||||||
|
|
||||||
|
bool is_subnet_index;
|
||||||
|
bool is_pattern_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TableType : public IndexType {
|
class TableType : public IndexType {
|
||||||
public:
|
public:
|
||||||
TableType(TypeListPtr ind, TypePtr yield);
|
TableType(TypeListPtr ind, TypePtr yield);
|
||||||
|
|
||||||
|
~TableType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assesses whether an &expire_func attribute's function type is compatible
|
* Assesses whether an &expire_func attribute's function type is compatible
|
||||||
* with this table type.
|
* with this table type.
|
||||||
|
@ -398,9 +402,17 @@ public:
|
||||||
// what one gets using an empty "set()" or "table()" constructor.
|
// what one gets using an empty "set()" or "table()" constructor.
|
||||||
bool IsUnspecifiedTable() const;
|
bool IsUnspecifiedTable() const;
|
||||||
|
|
||||||
|
const detail::CompositeHash* GetTableHash() const { return table_hash; }
|
||||||
|
|
||||||
|
// Called to rebuild the associated hash function when a record type
|
||||||
|
// (that this table type depends on) gets redefined during parsing.
|
||||||
|
void RegenerateHash();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool DoExpireCheck(const detail::AttrPtr& attr);
|
bool DoExpireCheck(const detail::AttrPtr& attr);
|
||||||
|
|
||||||
|
detail::CompositeHash* table_hash = nullptr;
|
||||||
|
|
||||||
// Used to prevent repeated error messages.
|
// Used to prevent repeated error messages.
|
||||||
bool reported_error = false;
|
bool reported_error = false;
|
||||||
};
|
};
|
||||||
|
|
34
src/Val.cc
34
src/Val.cc
|
@ -1568,7 +1568,6 @@ void TableVal::Init(TableTypePtr t, bool ordered) {
|
||||||
if ( table_type->IsPatternIndex() )
|
if ( table_type->IsPatternIndex() )
|
||||||
pattern_matcher = std::make_unique<detail::TablePatternMatcher>(this, table_type->Yield());
|
pattern_matcher = std::make_unique<detail::TablePatternMatcher>(this, table_type->Yield());
|
||||||
|
|
||||||
table_hash = new detail::CompositeHash(table_type->GetIndices());
|
|
||||||
if ( ordered )
|
if ( ordered )
|
||||||
table_val = new PDict<TableEntryVal>(DictOrder::ORDERED);
|
table_val = new PDict<TableEntryVal>(DictOrder::ORDERED);
|
||||||
else
|
else
|
||||||
|
@ -1581,7 +1580,6 @@ TableVal::~TableVal() {
|
||||||
if ( timer )
|
if ( timer )
|
||||||
detail::timer_mgr->Cancel(timer);
|
detail::timer_mgr->Cancel(timer);
|
||||||
|
|
||||||
delete table_hash;
|
|
||||||
delete table_val;
|
delete table_val;
|
||||||
delete expire_iterator;
|
delete expire_iterator;
|
||||||
}
|
}
|
||||||
|
@ -1756,7 +1754,7 @@ bool TableVal::AddTo(Val* val, bool is_first_init, bool propagate_ops) const {
|
||||||
auto* v = tble.value;
|
auto* v = tble.value;
|
||||||
|
|
||||||
if ( is_first_init && t->AsTable()->Lookup(k.get()) ) {
|
if ( is_first_init && t->AsTable()->Lookup(k.get()) ) {
|
||||||
auto key = table_hash->RecoverVals(*k);
|
auto key = GetTableHash()->RecoverVals(*k);
|
||||||
// ### Shouldn't complain if their values are equal.
|
// ### Shouldn't complain if their values are equal.
|
||||||
key->Warn("multiple initializations for index");
|
key->Warn("multiple initializations for index");
|
||||||
continue;
|
continue;
|
||||||
|
@ -2081,7 +2079,7 @@ bool TableVal::UpdateTimestamp(Val* index) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListValPtr TableVal::RecreateIndex(const detail::HashKey& k) const { return table_hash->RecoverVals(k); }
|
ListValPtr TableVal::RecreateIndex(const detail::HashKey& k) const { return GetTableHash()->RecoverVals(k); }
|
||||||
|
|
||||||
void TableVal::CallChangeFunc(const ValPtr& index, const ValPtr& old_value, OnChangeType tpe) {
|
void TableVal::CallChangeFunc(const ValPtr& index, const ValPtr& old_value, OnChangeType tpe) {
|
||||||
if ( ! change_func || ! index || in_change_func )
|
if ( ! change_func || ! index || in_change_func )
|
||||||
|
@ -2270,7 +2268,7 @@ ValPtr TableVal::Remove(const detail::HashKey& k, bool* iterators_invalidated) {
|
||||||
va = v->GetVal() ? v->GetVal() : IntrusivePtr{NewRef{}, this};
|
va = v->GetVal() ? v->GetVal() : IntrusivePtr{NewRef{}, this};
|
||||||
|
|
||||||
if ( subnets ) {
|
if ( subnets ) {
|
||||||
auto index = table_hash->RecoverVals(k);
|
auto index = GetTableHash()->RecoverVals(k);
|
||||||
|
|
||||||
if ( ! subnets->Remove(index.get()) )
|
if ( ! subnets->Remove(index.get()) )
|
||||||
reporter->InternalWarning("index not in prefix table");
|
reporter->InternalWarning("index not in prefix table");
|
||||||
|
@ -2281,7 +2279,7 @@ ValPtr TableVal::Remove(const detail::HashKey& k, bool* iterators_invalidated) {
|
||||||
Modified();
|
Modified();
|
||||||
|
|
||||||
if ( va && (change_func || ! broker_store.empty()) ) {
|
if ( va && (change_func || ! broker_store.empty()) ) {
|
||||||
auto index = table_hash->RecoverVals(k);
|
auto index = GetTableHash()->RecoverVals(k);
|
||||||
if ( ! broker_store.empty() )
|
if ( ! broker_store.empty() )
|
||||||
SendToStore(index.get(), nullptr, ELEMENT_REMOVED);
|
SendToStore(index.get(), nullptr, ELEMENT_REMOVED);
|
||||||
|
|
||||||
|
@ -2297,7 +2295,7 @@ ListValPtr TableVal::ToListVal(TypeTag t) const {
|
||||||
|
|
||||||
for ( const auto& tble : *table_val ) {
|
for ( const auto& tble : *table_val ) {
|
||||||
auto k = tble.GetHashKey();
|
auto k = tble.GetHashKey();
|
||||||
auto index = table_hash->RecoverVals(*k);
|
auto index = GetTableHash()->RecoverVals(*k);
|
||||||
|
|
||||||
if ( t == TYPE_ANY )
|
if ( t == TYPE_ANY )
|
||||||
l->Append(std::move(index));
|
l->Append(std::move(index));
|
||||||
|
@ -2329,7 +2327,7 @@ std::unordered_map<ValPtr, ValPtr> TableVal::ToMap() const {
|
||||||
for ( const auto& iter : *table_val ) {
|
for ( const auto& iter : *table_val ) {
|
||||||
auto k = iter.GetHashKey();
|
auto k = iter.GetHashKey();
|
||||||
auto v = iter.value;
|
auto v = iter.value;
|
||||||
auto vl = table_hash->RecoverVals(*k);
|
auto vl = GetTableHash()->RecoverVals(*k);
|
||||||
|
|
||||||
res[std::move(vl)] = v->GetVal();
|
res[std::move(vl)] = v->GetVal();
|
||||||
}
|
}
|
||||||
|
@ -2366,7 +2364,7 @@ void TableVal::Describe(ODesc* d) const {
|
||||||
auto k = iter->GetHashKey();
|
auto k = iter->GetHashKey();
|
||||||
auto* v = iter->value;
|
auto* v = iter->value;
|
||||||
|
|
||||||
auto vl = table_hash->RecoverVals(*k);
|
auto vl = GetTableHash()->RecoverVals(*k);
|
||||||
int dim = vl->Length();
|
int dim = vl->Length();
|
||||||
|
|
||||||
ODesc intermediary_d;
|
ODesc intermediary_d;
|
||||||
|
@ -2705,7 +2703,7 @@ unsigned int TableVal::ComputeFootprint(std::unordered_set<const Val*>* analyzed
|
||||||
|
|
||||||
for ( const auto& iter : *table_val ) {
|
for ( const auto& iter : *table_val ) {
|
||||||
auto k = iter.GetHashKey();
|
auto k = iter.GetHashKey();
|
||||||
auto vl = table_hash->RecoverVals(*k);
|
auto vl = GetTableHash()->RecoverVals(*k);
|
||||||
auto v = iter.value->GetVal();
|
auto v = iter.value->GetVal();
|
||||||
|
|
||||||
fp += vl->Footprint(analyzed_vals);
|
fp += vl->Footprint(analyzed_vals);
|
||||||
|
@ -2717,7 +2715,7 @@ unsigned int TableVal::ComputeFootprint(std::unordered_set<const Val*>* analyzed
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<detail::HashKey> TableVal::MakeHashKey(const Val& index) const {
|
std::unique_ptr<detail::HashKey> TableVal::MakeHashKey(const Val& index) const {
|
||||||
return table_hash->MakeHashKey(index, true);
|
return GetTableHash()->MakeHashKey(index, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableVal::SaveParseTimeTableState(RecordType* rt) {
|
void TableVal::SaveParseTimeTableState(RecordType* rt) {
|
||||||
|
@ -2733,8 +2731,17 @@ void TableVal::SaveParseTimeTableState(RecordType* rt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableVal::RebuildParseTimeTables() {
|
void TableVal::RebuildParseTimeTables() {
|
||||||
for ( auto& [tv, ptts] : parse_time_table_states )
|
std::set<TableType*> table_types; // regenerate hash just once per table type
|
||||||
|
|
||||||
|
for ( auto& [tv, ptts] : parse_time_table_states ) {
|
||||||
|
auto* tt = tv->table_type.get();
|
||||||
|
if ( table_types.count(tt) == 0 ) {
|
||||||
|
tt->RegenerateHash();
|
||||||
|
table_types.insert(tt);
|
||||||
|
}
|
||||||
|
|
||||||
tv->RebuildTable(std::move(ptts));
|
tv->RebuildTable(std::move(ptts));
|
||||||
|
}
|
||||||
|
|
||||||
parse_time_table_states.clear();
|
parse_time_table_states.clear();
|
||||||
}
|
}
|
||||||
|
@ -2755,9 +2762,6 @@ TableVal::ParseTimeTableState TableVal::DumpTableState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableVal::RebuildTable(ParseTimeTableState ptts) {
|
void TableVal::RebuildTable(ParseTimeTableState ptts) {
|
||||||
delete table_hash;
|
|
||||||
table_hash = new detail::CompositeHash(table_type->GetIndices());
|
|
||||||
|
|
||||||
for ( auto& [key, val] : ptts )
|
for ( auto& [key, val] : ptts )
|
||||||
Assign(std::move(key), std::move(val));
|
Assign(std::move(key), std::move(val));
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ namespace detail {
|
||||||
class ScriptFunc;
|
class ScriptFunc;
|
||||||
class Frame;
|
class Frame;
|
||||||
class PrefixTable;
|
class PrefixTable;
|
||||||
class CompositeHash;
|
|
||||||
class HashKey;
|
class HashKey;
|
||||||
class TablePatternMatcher;
|
class TablePatternMatcher;
|
||||||
|
|
||||||
|
@ -930,7 +929,7 @@ public:
|
||||||
|
|
||||||
const PDict<TableEntryVal>* Get() const { return table_val; }
|
const PDict<TableEntryVal>* Get() const { return table_val; }
|
||||||
|
|
||||||
const detail::CompositeHash* GetTableHash() const { return table_hash; }
|
const detail::CompositeHash* GetTableHash() const { return table_type->GetTableHash(); }
|
||||||
|
|
||||||
// Returns the size of the table.
|
// Returns the size of the table.
|
||||||
int Size() const;
|
int Size() const;
|
||||||
|
@ -1043,7 +1042,6 @@ protected:
|
||||||
ValPtr DoClone(CloneState* state) override;
|
ValPtr DoClone(CloneState* state) override;
|
||||||
|
|
||||||
TableTypePtr table_type;
|
TableTypePtr table_type;
|
||||||
detail::CompositeHash* table_hash;
|
|
||||||
detail::AttributesPtr attrs;
|
detail::AttributesPtr attrs;
|
||||||
detail::ExprPtr expire_time;
|
detail::ExprPtr expire_time;
|
||||||
detail::ExprPtr expire_func;
|
detail::ExprPtr expire_func;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue