mirror of
https://github.com/zeek/zeek.git
synced 2025-10-13 12:08:20 +00:00
Improve TableVal HashKey management
* Deprecated ComputeHash() methods and replaced with MakeHashKey() which returns std::unique_ptr<HashKey> * Deprecated RecoverIndex() and replaced with RecreateIndex() which takes HashKey& and returns IntrusivePtr. * Updated the new TableVal Assign()/Remove() methods to take either std::unique_ptr<HashKey> or HashKey& as appropriate for clarity of ownership expectations.
This commit is contained in:
parent
8a6a92c348
commit
3f92df51b7
18 changed files with 137 additions and 114 deletions
72
src/Val.cc
72
src/Val.cc
|
@ -540,7 +540,7 @@ static void BuildJSON(threading::formatter::JSON::NullDoubleWriter& writer, Val*
|
|||
auto c = table->InitForIteration();
|
||||
while ( (entry = table->NextEntry(k, c)) )
|
||||
{
|
||||
auto lv = tval->RecoverIndex(k);
|
||||
auto lv = tval->RecreateIndex(*k);
|
||||
delete k;
|
||||
Val* entry_key = lv->Length() == 1 ? lv->Idx(0).get() : lv.get();
|
||||
|
||||
|
@ -1508,14 +1508,15 @@ void TableVal::CheckExpireAttr(attr_tag at)
|
|||
|
||||
bool TableVal::Assign(IntrusivePtr<Val> index, IntrusivePtr<Val> new_val)
|
||||
{
|
||||
HashKey* k = ComputeHash(*index);
|
||||
auto k = MakeHashKey(*index);
|
||||
|
||||
if ( ! k )
|
||||
{
|
||||
index->Error("index type doesn't match table", table_type->Indices());
|
||||
return false;
|
||||
}
|
||||
|
||||
return Assign(std::move(index), k, std::move(new_val));
|
||||
return Assign(std::move(index), std::move(k), std::move(new_val));
|
||||
}
|
||||
|
||||
bool TableVal::Assign(Val* index, Val* new_val)
|
||||
|
@ -1523,7 +1524,8 @@ bool TableVal::Assign(Val* index, Val* new_val)
|
|||
return Assign({NewRef{}, index}, {AdoptRef{}, new_val});
|
||||
}
|
||||
|
||||
bool TableVal::Assign(IntrusivePtr<Val> index, HashKey* k, IntrusivePtr<Val> new_val)
|
||||
bool TableVal::Assign(IntrusivePtr<Val> index, std::unique_ptr<HashKey> k,
|
||||
IntrusivePtr<Val> new_val)
|
||||
{
|
||||
bool is_set = table_type->IsSet();
|
||||
|
||||
|
@ -1532,19 +1534,18 @@ bool TableVal::Assign(IntrusivePtr<Val> index, HashKey* k, IntrusivePtr<Val> new
|
|||
|
||||
TableEntryVal* new_entry_val = new TableEntryVal(new_val);
|
||||
HashKey k_copy(k->Key(), k->Size(), k->Hash());
|
||||
TableEntryVal* old_entry_val = AsNonConstTable()->Insert(k, new_entry_val);
|
||||
TableEntryVal* old_entry_val = AsNonConstTable()->Insert(k.get(), new_entry_val);
|
||||
|
||||
// If the dictionary index already existed, the insert may free up the
|
||||
// memory allocated to the key bytes, so have to assume k is invalid
|
||||
// from here on out.
|
||||
delete k;
|
||||
k = nullptr;
|
||||
|
||||
if ( subnets )
|
||||
{
|
||||
if ( ! index )
|
||||
{
|
||||
auto v = RecoverIndex(&k_copy);
|
||||
auto v = RecreateIndex(k_copy);
|
||||
subnets->Insert(v.get(), new_entry_val);
|
||||
}
|
||||
else
|
||||
|
@ -1559,7 +1560,7 @@ bool TableVal::Assign(IntrusivePtr<Val> index, HashKey* k, IntrusivePtr<Val> new
|
|||
|
||||
if ( change_func )
|
||||
{
|
||||
auto change_index = index ? std::move(index) : RecoverIndex(&k_copy);
|
||||
auto change_index = index ? std::move(index) : RecreateIndex(k_copy);
|
||||
auto v = old_entry_val ? old_entry_val->GetVal() : new_val;
|
||||
CallChangeFunc(change_index.get(), v.get(), old_entry_val ? ELEMENT_CHANGED : ELEMENT_NEW);
|
||||
}
|
||||
|
@ -1571,7 +1572,7 @@ bool TableVal::Assign(IntrusivePtr<Val> index, HashKey* k, IntrusivePtr<Val> new
|
|||
|
||||
bool TableVal::Assign(Val* index, HashKey* k, Val* new_val)
|
||||
{
|
||||
return Assign({NewRef{}, index}, k, {AdoptRef{}, new_val});
|
||||
return Assign({NewRef{}, index}, std::unique_ptr<HashKey>{k}, {AdoptRef{}, new_val});
|
||||
}
|
||||
|
||||
IntrusivePtr<Val> TableVal::SizeVal() const
|
||||
|
@ -1607,9 +1608,11 @@ bool TableVal::AddTo(Val* val, bool is_first_init, bool propagate_ops) const
|
|||
TableEntryVal* v;
|
||||
while ( (v = tbl->NextEntry(k, c)) )
|
||||
{
|
||||
std::unique_ptr<HashKey> hk{k};
|
||||
|
||||
if ( is_first_init && t->AsTable()->Lookup(k) )
|
||||
{
|
||||
auto key = table_hash->RecoverVals(k);
|
||||
auto key = table_hash->RecoverVals(*k);
|
||||
// ### Shouldn't complain if their values are equal.
|
||||
key->Warn("multiple initializations for index");
|
||||
continue;
|
||||
|
@ -1617,12 +1620,12 @@ bool TableVal::AddTo(Val* val, bool is_first_init, bool propagate_ops) const
|
|||
|
||||
if ( type->IsSet() )
|
||||
{
|
||||
if ( ! t->Assign(v->GetVal(), k, nullptr) )
|
||||
if ( ! t->Assign(v->GetVal(), std::move(hk), nullptr) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ! t->Assign(nullptr, k, v->GetVal()) )
|
||||
if ( ! t->Assign(nullptr, std::move(hk), v->GetVal()) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1657,7 +1660,7 @@ bool TableVal::RemoveFrom(Val* val) const
|
|||
// OTOH, they are both the same type, so as long as
|
||||
// we don't have hash keys that are keyed per dictionary,
|
||||
// it should work ...
|
||||
t->Remove(k);
|
||||
t->Remove(*k);
|
||||
delete k;
|
||||
}
|
||||
|
||||
|
@ -1910,11 +1913,11 @@ const IntrusivePtr<Val>& TableVal::Find(const IntrusivePtr<Val>& index)
|
|||
|
||||
if ( tbl->Length() > 0 )
|
||||
{
|
||||
HashKey* k = ComputeHash(*index);
|
||||
auto k = MakeHashKey(*index);
|
||||
|
||||
if ( k )
|
||||
{
|
||||
TableEntryVal* v = AsTable()->Lookup(k);
|
||||
delete k;
|
||||
TableEntryVal* v = AsTable()->Lookup(k.get());
|
||||
|
||||
if ( v )
|
||||
{
|
||||
|
@ -2006,13 +2009,12 @@ bool TableVal::UpdateTimestamp(Val* index)
|
|||
v = (TableEntryVal*) subnets->Lookup(index);
|
||||
else
|
||||
{
|
||||
HashKey* k = ComputeHash(*index);
|
||||
auto k = MakeHashKey(*index);
|
||||
|
||||
if ( ! k )
|
||||
return false;
|
||||
|
||||
v = AsTable()->Lookup(k);
|
||||
|
||||
delete k;
|
||||
v = AsTable()->Lookup(k.get());
|
||||
}
|
||||
|
||||
if ( ! v )
|
||||
|
@ -2023,7 +2025,7 @@ bool TableVal::UpdateTimestamp(Val* index)
|
|||
return true;
|
||||
}
|
||||
|
||||
IntrusivePtr<ListVal> TableVal::RecoverIndex(const HashKey* k) const
|
||||
IntrusivePtr<ListVal> TableVal::RecreateIndex(const HashKey& k) const
|
||||
{
|
||||
return table_hash->RecoverVals(k);
|
||||
}
|
||||
|
@ -2091,8 +2093,8 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
|
|||
|
||||
IntrusivePtr<Val> TableVal::Remove(const Val& index)
|
||||
{
|
||||
HashKey* k = ComputeHash(index);
|
||||
TableEntryVal* v = k ? AsNonConstTable()->RemoveEntry(k) : nullptr;
|
||||
auto k = MakeHashKey(index);
|
||||
TableEntryVal* v = k ? AsNonConstTable()->RemoveEntry(k.get()) : nullptr;
|
||||
IntrusivePtr<Val> va;
|
||||
|
||||
if ( v )
|
||||
|
@ -2101,7 +2103,6 @@ IntrusivePtr<Val> TableVal::Remove(const Val& index)
|
|||
if ( subnets && ! subnets->Remove(&index) )
|
||||
reporter->InternalWarning("index not in prefix table");
|
||||
|
||||
delete k;
|
||||
delete v;
|
||||
|
||||
Modified();
|
||||
|
@ -2112,7 +2113,7 @@ IntrusivePtr<Val> TableVal::Remove(const Val& index)
|
|||
return va;
|
||||
}
|
||||
|
||||
IntrusivePtr<Val> TableVal::Remove(const HashKey* k)
|
||||
IntrusivePtr<Val> TableVal::Remove(const HashKey& k)
|
||||
{
|
||||
TableEntryVal* v = AsNonConstTable()->RemoveEntry(k);
|
||||
IntrusivePtr<Val> va;
|
||||
|
@ -2151,7 +2152,7 @@ IntrusivePtr<ListVal> TableVal::ToListVal(TypeTag t) const
|
|||
HashKey* k;
|
||||
while ( tbl->NextEntry(k, c) )
|
||||
{
|
||||
auto index = table_hash->RecoverVals(k);
|
||||
auto index = table_hash->RecoverVals(*k);
|
||||
|
||||
if ( t == TYPE_ANY )
|
||||
l->Append(std::move(index));
|
||||
|
@ -2226,7 +2227,7 @@ void TableVal::Describe(ODesc* d) const
|
|||
if ( ! v )
|
||||
reporter->InternalError("hash table underflow in TableVal::Describe");
|
||||
|
||||
auto vl = table_hash->RecoverVals(k);
|
||||
auto vl = table_hash->RecoverVals(*k);
|
||||
int dim = vl->Length();
|
||||
|
||||
if ( i > 0 )
|
||||
|
@ -2398,7 +2399,7 @@ void TableVal::DoExpire(double t)
|
|||
|
||||
if ( expire_func )
|
||||
{
|
||||
idx = RecoverIndex(k);
|
||||
idx = RecreateIndex(*k);
|
||||
double secs = CallExpireFunc(idx);
|
||||
|
||||
// It's possible that the user-provided
|
||||
|
@ -2428,7 +2429,7 @@ void TableVal::DoExpire(double t)
|
|||
if ( subnets )
|
||||
{
|
||||
if ( ! idx )
|
||||
idx = RecoverIndex(k);
|
||||
idx = RecreateIndex(*k);
|
||||
if ( ! subnets->Remove(idx.get()) )
|
||||
reporter->InternalWarning("index not in prefix table");
|
||||
}
|
||||
|
@ -2437,7 +2438,7 @@ void TableVal::DoExpire(double t)
|
|||
if ( change_func )
|
||||
{
|
||||
if ( ! idx )
|
||||
idx = RecoverIndex(k);
|
||||
idx = RecreateIndex(*k);
|
||||
CallChangeFunc(idx.get(), v->GetVal().get(), ELEMENT_EXPIRED);
|
||||
}
|
||||
|
||||
|
@ -2568,7 +2569,7 @@ IntrusivePtr<Val> TableVal::DoClone(CloneState* state)
|
|||
|
||||
if ( subnets )
|
||||
{
|
||||
auto idx = RecoverIndex(key);
|
||||
auto idx = RecreateIndex(*key);
|
||||
tv->subnets->Insert(idx.get(), nval);
|
||||
}
|
||||
|
||||
|
@ -2615,9 +2616,12 @@ unsigned int TableVal::MemoryAllocation() const
|
|||
+ table_hash->MemoryAllocation();
|
||||
}
|
||||
|
||||
HashKey* TableVal::ComputeHash(const Val& index) const
|
||||
HashKey* TableVal::ComputeHash(const Val* index) const
|
||||
{ return MakeHashKey(*index).release(); }
|
||||
|
||||
std::unique_ptr<HashKey> TableVal::MakeHashKey(const Val& index) const
|
||||
{
|
||||
return table_hash->ComputeHash(index, true);
|
||||
return table_hash->MakeHashKey(index, true);
|
||||
}
|
||||
|
||||
void TableVal::SaveParseTimeTableState(RecordType* rt)
|
||||
|
@ -2658,7 +2662,7 @@ TableVal::ParseTimeTableState TableVal::DumpTableState()
|
|||
|
||||
while ( (val = tbl->NextEntry(key, cookie)) )
|
||||
{
|
||||
rval.emplace_back(RecoverIndex(key), val->GetVal());
|
||||
rval.emplace_back(RecreateIndex(*key), val->GetVal());
|
||||
delete key;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue