logging speedup by switching to raw record access

This commit is contained in:
Vern Paxson 2023-04-10 11:43:19 -07:00
parent f866252e5e
commit 4600ca41f6
3 changed files with 65 additions and 28 deletions

View file

@ -52,9 +52,15 @@ class HashKey;
class ValTrace; class ValTrace;
class ZBody; class ZBody;
class CPPRuntime;
} // namespace detail } // namespace detail
namespace logging
{
class Manager;
}
namespace run_state namespace run_state
{ {
@ -1403,8 +1409,10 @@ public:
static void DoneParsing(); static void DoneParsing();
protected: protected:
friend class zeek::logging::Manager;
friend class zeek::detail::ValTrace; friend class zeek::detail::ValTrace;
friend class zeek::detail::ZBody; friend class zeek::detail::ZBody;
friend class zeek::detail::CPPRuntime;
RecordValPtr DoCoerceTo(RecordTypePtr other, bool allow_orphaning) const; RecordValPtr DoCoerceTo(RecordTypePtr other, bool allow_orphaning) const;

View file

@ -973,11 +973,8 @@ bool Manager::Write(EnumVal* id, RecordVal* columns_arg)
return true; return true;
} }
threading::Value* Manager::ValToLogVal(Val* val, Type* ty) threading::Value* Manager::ValToLogVal(std::optional<ZVal>& val, Type* ty)
{ {
if ( ! ty )
ty = val->GetType().get();
if ( ! val ) if ( ! val )
return new threading::Value(ty->Tag(), false); return new threading::Value(ty->Tag(), false);
@ -987,12 +984,12 @@ threading::Value* Manager::ValToLogVal(Val* val, Type* ty)
{ {
case TYPE_BOOL: case TYPE_BOOL:
case TYPE_INT: case TYPE_INT:
lval->val.int_val = val->InternalInt(); lval->val.int_val = val->AsInt();
break; break;
case TYPE_ENUM: case TYPE_ENUM:
{ {
const char* s = val->GetType()->AsEnumType()->Lookup(val->InternalInt()); const char* s = ty->AsEnumType()->Lookup(val->AsInt());
if ( s ) if ( s )
{ {
@ -1002,7 +999,8 @@ threading::Value* Manager::ValToLogVal(Val* val, Type* ty)
else else
{ {
val->GetType()->Error("enum type does not contain value", val); auto err_msg = "enum type does not contain value:" + std::to_string(val->AsInt());
ty->Error(err_msg.c_str());
lval->val.string_val.data = util::copy_string(""); lval->val.string_val.data = util::copy_string("");
lval->val.string_val.length = 0; lval->val.string_val.length = 0;
} }
@ -1010,31 +1008,44 @@ threading::Value* Manager::ValToLogVal(Val* val, Type* ty)
} }
case TYPE_COUNT: case TYPE_COUNT:
lval->val.uint_val = val->InternalUnsigned(); lval->val.uint_val = val->AsCount();
break; break;
case TYPE_PORT: case TYPE_PORT:
lval->val.port_val.port = val->AsPortVal()->Port(); {
lval->val.port_val.proto = val->AsPortVal()->PortType(); auto p = val->AsCount();
auto pt = TRANSPORT_UNKNOWN;
auto pm = p & PORT_SPACE_MASK;
if ( pm == TCP_PORT_MASK )
pt = TRANSPORT_TCP;
else if ( pm == UDP_PORT_MASK )
pt = TRANSPORT_UDP;
else if ( pm == ICMP_PORT_MASK )
pt = TRANSPORT_ICMP;
lval->val.port_val.port = p & ~PORT_SPACE_MASK;
lval->val.port_val.proto = pt;
break; break;
}
case TYPE_SUBNET: case TYPE_SUBNET:
val->AsSubNet().ConvertToThreadingValue(&lval->val.subnet_val); val->AsSubNet()->Get().ConvertToThreadingValue(&lval->val.subnet_val);
break; break;
case TYPE_ADDR: case TYPE_ADDR:
val->AsAddr().ConvertToThreadingValue(&lval->val.addr_val); val->AsAddr()->Get().ConvertToThreadingValue(&lval->val.addr_val);
break; break;
case TYPE_DOUBLE: case TYPE_DOUBLE:
case TYPE_TIME: case TYPE_TIME:
case TYPE_INTERVAL: case TYPE_INTERVAL:
lval->val.double_val = val->InternalDouble(); lval->val.double_val = val->AsDouble();
break; break;
case TYPE_STRING: case TYPE_STRING:
{ {
const String* s = val->AsString(); const String* s = val->AsString()->AsString();
char* buf = new char[s->Len()]; char* buf = new char[s->Len()];
memcpy(buf, s->Bytes(), s->Len()); memcpy(buf, s->Bytes(), s->Len());
@ -1065,31 +1076,44 @@ threading::Value* Manager::ValToLogVal(Val* val, Type* ty)
case TYPE_TABLE: case TYPE_TABLE:
{ {
auto set = val->AsTableVal()->ToPureListVal(); auto tbl = val->AsTable();
auto set = tbl->ToPureListVal();
if ( ! set ) if ( ! set )
// ToPureListVal has reported an internal warning // ToPureListVal has reported an internal warning
// already. Just keep going by making something up. // already. Just keep going by making something up.
set = make_intrusive<ListVal>(TYPE_INT); set = make_intrusive<ListVal>(TYPE_INT);
auto tbl_t = cast_intrusive<TableType>(tbl->GetType());
auto& set_t = tbl_t->GetIndexTypes()[0];
bool is_managed = ZVal::IsManagedType(set_t);
lval->val.set_val.size = set->Length(); lval->val.set_val.size = set->Length();
lval->val.set_val.vals = new threading::Value*[lval->val.set_val.size]; lval->val.set_val.vals = new threading::Value*[lval->val.set_val.size];
for ( zeek_int_t i = 0; i < lval->val.set_val.size; i++ ) for ( zeek_int_t i = 0; i < lval->val.set_val.size; i++ )
lval->val.set_val.vals[i] = ValToLogVal(set->Idx(i).get()); {
std::optional<ZVal> s_i = ZVal(set->Idx(i), set_t);
lval->val.set_val.vals[i] = ValToLogVal(s_i, set_t.get());
if ( is_managed )
ZVal::DeleteManagedType(*s_i);
}
break; break;
} }
case TYPE_VECTOR: case TYPE_VECTOR:
{ {
VectorVal* vec = val->AsVectorVal(); VectorVal* vec = val->AsVector();
lval->val.vector_val.size = vec->Size(); lval->val.vector_val.size = vec->Size();
lval->val.vector_val.vals = new threading::Value*[lval->val.vector_val.size]; lval->val.vector_val.vals = new threading::Value*[lval->val.vector_val.size];
auto& vv = vec->RawVec();
auto& vt = vec->GetType()->Yield();
for ( zeek_int_t i = 0; i < lval->val.vector_val.size; i++ ) for ( zeek_int_t i = 0; i < lval->val.vector_val.size; i++ )
{ {
lval->val.vector_val.vals[i] = ValToLogVal(vec->ValAt(i).get(), lval->val.vector_val.vals[i] = ValToLogVal((*vv)[i], vt.get());
vec->GetType()->Yield().get());
} }
break; break;
@ -1118,7 +1142,8 @@ threading::Value** Manager::RecordToFilterVals(Stream* stream, Filter* filter, R
for ( int i = 0; i < filter->num_fields; ++i ) for ( int i = 0; i < filter->num_fields; ++i )
{ {
Val* val; std::optional<ZVal> val;
Type* vt;
if ( i < filter->num_ext_fields ) if ( i < filter->num_ext_fields )
{ {
if ( ! ext_rec ) if ( ! ext_rec )
@ -1128,21 +1153,23 @@ threading::Value** Manager::RecordToFilterVals(Stream* stream, Filter* filter, R
continue; continue;
} }
val = ext_rec.get(); val = ZVal(ext_rec.get());
vt = ext_rec->GetType().get();
} }
else else
val = columns; {
val = ZVal(columns);
vt = columns->GetType().get();
}
// For each field, first find the right value, which can // For each field, first find the right value, which can
// potentially be nested inside other records. // potentially be nested inside other records.
list<int>& indices = filter->indices[i]; list<int>& indices = filter->indices[i];
ValPtr val_ptr;
for ( list<int>::iterator j = indices.begin(); j != indices.end(); ++j ) for ( list<int>::iterator j = indices.begin(); j != indices.end(); ++j )
{ {
val_ptr = val->AsRecordVal()->GetField(*j); auto vr = val->AsRecord();
val = val_ptr.get(); val = vr->RawOptField(*j);
if ( ! val ) if ( ! val )
{ {
@ -1150,10 +1177,12 @@ threading::Value** Manager::RecordToFilterVals(Stream* stream, Filter* filter, R
vals[i] = new threading::Value(filter->fields[i]->type, false); vals[i] = new threading::Value(filter->fields[i]->type, false);
break; break;
} }
vt = cast_intrusive<RecordType>(vr->GetType())->GetFieldType(*j).get();
} }
if ( val ) if ( val )
vals[i] = ValToLogVal(val); vals[i] = ValToLogVal(val, vt);
} }
return vals; return vals;

View file

@ -291,7 +291,7 @@ private:
threading::Value** RecordToFilterVals(Stream* stream, Filter* filter, RecordVal* columns); threading::Value** RecordToFilterVals(Stream* stream, Filter* filter, RecordVal* columns);
threading::Value* ValToLogVal(Val* val, Type* ty = nullptr); threading::Value* ValToLogVal(std::optional<ZVal>& val, Type* ty);
Stream* FindStream(EnumVal* id); Stream* FindStream(EnumVal* id);
void RemoveDisabledWriters(Stream* stream); void RemoveDisabledWriters(Stream* stream);
void InstallRotationTimer(WriterInfo* winfo); void InstallRotationTimer(WriterInfo* winfo);