mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +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
|
@ -229,7 +229,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
while ( tbl->NextEntry(k, it) )
|
||||
{
|
||||
hashkeys[k] = idx++;
|
||||
lv->Append(tv->RecoverIndex(k));
|
||||
lv->Append(tv->RecreateIndex(*k));
|
||||
}
|
||||
|
||||
for ( auto& kv : hashkeys )
|
||||
|
@ -333,7 +333,7 @@ char* CompositeHash::SingleValHash(bool type_check, char* kp0,
|
|||
}
|
||||
|
||||
|
||||
HashKey* CompositeHash::ComputeHash(const Val& argv, bool type_check) const
|
||||
std::unique_ptr<HashKey> CompositeHash::MakeHashKey(const Val& argv, bool type_check) const
|
||||
{
|
||||
auto v = &argv;
|
||||
|
||||
|
@ -349,8 +349,7 @@ HashKey* CompositeHash::ComputeHash(const Val& argv, bool type_check) const
|
|||
// be okay; the only thing is that the ListVal unref's it.
|
||||
Val* ncv = (Val*) v;
|
||||
lv.Append({NewRef{}, ncv});
|
||||
HashKey* hk = ComputeHash(lv, type_check);
|
||||
return hk;
|
||||
return MakeHashKey(lv, type_check);
|
||||
}
|
||||
|
||||
char* k = key;
|
||||
|
@ -383,10 +382,10 @@ HashKey* CompositeHash::ComputeHash(const Val& argv, bool type_check) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return new HashKey((k == key), (void*) k, kp - k);
|
||||
return std::make_unique<HashKey>((k == key), (void*) k, kp - k);
|
||||
}
|
||||
|
||||
HashKey* CompositeHash::ComputeSingletonHash(const Val* v, bool type_check) const
|
||||
std::unique_ptr<HashKey> CompositeHash::ComputeSingletonHash(const Val* v, bool type_check) const
|
||||
{
|
||||
if ( v->GetType()->Tag() == TYPE_LIST )
|
||||
{
|
||||
|
@ -404,21 +403,21 @@ HashKey* CompositeHash::ComputeSingletonHash(const Val* v, bool type_check) cons
|
|||
switch ( singleton_tag ) {
|
||||
case TYPE_INTERNAL_INT:
|
||||
case TYPE_INTERNAL_UNSIGNED:
|
||||
return new HashKey(v->ForceAsInt());
|
||||
return std::make_unique<HashKey>(v->ForceAsInt());
|
||||
|
||||
case TYPE_INTERNAL_ADDR:
|
||||
return v->AsAddr().GetHashKey();
|
||||
return v->AsAddr().MakeHashKey();
|
||||
|
||||
case TYPE_INTERNAL_SUBNET:
|
||||
return v->AsSubNet().GetHashKey();
|
||||
return v->AsSubNet().MakeHashKey();
|
||||
|
||||
case TYPE_INTERNAL_DOUBLE:
|
||||
return new HashKey(v->InternalDouble());
|
||||
return std::make_unique<HashKey>(v->InternalDouble());
|
||||
|
||||
case TYPE_INTERNAL_VOID:
|
||||
case TYPE_INTERNAL_OTHER:
|
||||
if ( v->GetType()->Tag() == TYPE_FUNC )
|
||||
return new HashKey(v->AsFunc()->GetUniqueFuncID());
|
||||
return std::make_unique<HashKey>(v->AsFunc()->GetUniqueFuncID());
|
||||
|
||||
if ( v->GetType()->Tag() == TYPE_PATTERN )
|
||||
{
|
||||
|
@ -430,14 +429,14 @@ HashKey* CompositeHash::ComputeSingletonHash(const Val* v, bool type_check) cons
|
|||
char* key = new char[n];
|
||||
std::memcpy(key, texts[0], strlen(texts[0]) + 1);
|
||||
std::memcpy(key + strlen(texts[0]) + 1, texts[1], strlen(texts[1]) + 1);
|
||||
return new HashKey(false, key, n);
|
||||
return std::make_unique<HashKey>(false, key, n);
|
||||
}
|
||||
|
||||
reporter->InternalError("bad index type in CompositeHash::ComputeSingletonHash");
|
||||
return nullptr;
|
||||
|
||||
case TYPE_INTERNAL_STRING:
|
||||
return new HashKey(v->AsString());
|
||||
return std::make_unique<HashKey>(v->AsString());
|
||||
|
||||
case TYPE_INTERNAL_ERROR:
|
||||
return nullptr;
|
||||
|
@ -707,12 +706,12 @@ int CompositeHash::SizeAlign(int offset, unsigned int size) const
|
|||
return offset;
|
||||
}
|
||||
|
||||
IntrusivePtr<ListVal> CompositeHash::RecoverVals(const HashKey* k) const
|
||||
IntrusivePtr<ListVal> CompositeHash::RecoverVals(const HashKey& k) const
|
||||
{
|
||||
auto l = make_intrusive<ListVal>(TYPE_ANY);
|
||||
const auto& tl = type->Types();
|
||||
const char* kp = (const char*) k->Key();
|
||||
const char* const k_end = kp + k->Size();
|
||||
const char* kp = (const char*) k.Key();
|
||||
const char* const k_end = kp + k.Size();
|
||||
|
||||
for ( const auto& type : tl )
|
||||
{
|
||||
|
@ -728,12 +727,12 @@ IntrusivePtr<ListVal> CompositeHash::RecoverVals(const HashKey* k) const
|
|||
return l;
|
||||
}
|
||||
|
||||
const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
|
||||
const char* CompositeHash::RecoverOneVal(const HashKey& k, const char* kp0,
|
||||
const char* const k_end, BroType* t,
|
||||
IntrusivePtr<Val>* pval, bool optional) const
|
||||
{
|
||||
// k->Size() == 0 for a single empty string.
|
||||
if ( kp0 >= k_end && k->Size() > 0 )
|
||||
if ( kp0 >= k_end && k.Size() > 0 )
|
||||
reporter->InternalError("over-ran key in CompositeHash::RecoverVals");
|
||||
|
||||
TypeTag tag = t->Tag();
|
||||
|
@ -874,7 +873,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
|
|||
kp1 = kp0;
|
||||
int divider = strlen(kp0) + 1;
|
||||
re = new RE_Matcher(kp1, kp1 + divider);
|
||||
kp1 += k->Size();
|
||||
kp1 += k.Size();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1033,7 +1032,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
|
|||
if ( is_singleton )
|
||||
{
|
||||
kp1 = kp0;
|
||||
n = k->Size();
|
||||
n = k.Size();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "Type.h"
|
||||
#include "IntrusivePtr.h"
|
||||
|
||||
|
@ -15,19 +17,23 @@ public:
|
|||
|
||||
// Compute the hash corresponding to the given index val,
|
||||
// or nullptr if it fails to typecheck.
|
||||
HashKey* ComputeHash(const Val& v, bool type_check) const;
|
||||
std::unique_ptr<HashKey> MakeHashKey(const Val& v, bool type_check) const;
|
||||
|
||||
[[deprecated("Remove in v4.1. Pass a Val& instead.")]]
|
||||
[[deprecated("Remove in v4.1. Use MakeHashKey().")]]
|
||||
HashKey* ComputeHash(const Val* v, bool type_check) const
|
||||
{ return ComputeHash(*v, type_check); }
|
||||
{ return MakeHashKey(*v, type_check).release(); }
|
||||
|
||||
// Given a hash key, recover the values used to create it.
|
||||
IntrusivePtr<ListVal> RecoverVals(const HashKey* k) const;
|
||||
IntrusivePtr<ListVal> RecoverVals(const HashKey& k) const;
|
||||
|
||||
[[deprecated("Remove in v4.1. Pass in HashKey& instead.")]]
|
||||
IntrusivePtr<ListVal> RecoverVals(const HashKey* k) const
|
||||
{ return RecoverVals(*k); }
|
||||
|
||||
unsigned int MemoryAllocation() const { return padded_sizeof(*this) + pad_size(size); }
|
||||
|
||||
protected:
|
||||
HashKey* ComputeSingletonHash(const Val* v, bool type_check) const;
|
||||
std::unique_ptr<HashKey> ComputeSingletonHash(const Val* v, bool type_check) const;
|
||||
|
||||
// Computes the piece of the hash for Val*, returning the new kp.
|
||||
// Used as a helper for ComputeHash in the non-singleton case.
|
||||
|
@ -38,7 +44,7 @@ protected:
|
|||
// Upon return, pval will point to the recovered Val of type t.
|
||||
// Returns and updated kp for the next Val. Calls reporter->InternalError()
|
||||
// upon errors, so there is no return value for invalid input.
|
||||
const char* RecoverOneVal(const HashKey* k,
|
||||
const char* RecoverOneVal(const HashKey& k,
|
||||
const char* kp, const char* const k_end,
|
||||
BroType* t, IntrusivePtr<Val>* pval, bool optional) const;
|
||||
|
||||
|
|
|
@ -218,4 +218,6 @@ public:
|
|||
{ return (T*) Dictionary::NextEntry(h, cookie, 1); }
|
||||
T* RemoveEntry(const HashKey* key)
|
||||
{ return (T*) Remove(key->Key(), key->Size(), key->Hash()); }
|
||||
T* RemoveEntry(const HashKey& key)
|
||||
{ return (T*) Remove(key.Key(), key.Size(), key.Hash()); }
|
||||
};
|
||||
|
|
|
@ -53,8 +53,11 @@ IPAddr::IPAddr(const BroString& s)
|
|||
}
|
||||
|
||||
HashKey* IPAddr::GetHashKey() const
|
||||
{ return MakeHashKey().release(); }
|
||||
|
||||
std::unique_ptr<HashKey> IPAddr::MakeHashKey() const
|
||||
{
|
||||
return new HashKey((void*)in6.s6_addr, sizeof(in6.s6_addr));
|
||||
return std::make_unique<HashKey>((void*)in6.s6_addr, sizeof(in6.s6_addr));
|
||||
}
|
||||
|
||||
static inline uint32_t bit_mask32(int bottom_bits)
|
||||
|
@ -303,6 +306,9 @@ std::string IPPrefix::AsString() const
|
|||
}
|
||||
|
||||
HashKey* IPPrefix::GetHashKey() const
|
||||
{ return MakeHashKey().release(); }
|
||||
|
||||
std::unique_ptr<HashKey> IPPrefix::MakeHashKey() const
|
||||
{
|
||||
struct {
|
||||
in6_addr ip;
|
||||
|
@ -312,7 +318,7 @@ HashKey* IPPrefix::GetHashKey() const
|
|||
key.ip = prefix.in6;
|
||||
key.len = Length();
|
||||
|
||||
return new HashKey(&key, sizeof(key));
|
||||
return std::make_unique<HashKey>(&key, sizeof(key));
|
||||
}
|
||||
|
||||
bool IPPrefix::ConvertString(const char* text, IPPrefix* result)
|
||||
|
|
13
src/IPAddr.h
13
src/IPAddr.h
|
@ -6,6 +6,7 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "threading/SerialTypes.h"
|
||||
|
||||
|
@ -247,9 +248,11 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a key that can be used to lookup the IP Address in a hash
|
||||
* table. Passes ownership to caller.
|
||||
* Returns a key that can be used to lookup the IP Address in a hash table.
|
||||
*/
|
||||
std::unique_ptr<HashKey> MakeHashKey() const;
|
||||
|
||||
[[deprecated("Remove in v4.1. Use MakeHashKey().")]]
|
||||
HashKey* GetHashKey() const;
|
||||
|
||||
/**
|
||||
|
@ -629,9 +632,11 @@ public:
|
|||
operator std::string() const { return AsString(); }
|
||||
|
||||
/**
|
||||
* Returns a key that can be used to lookup the IP Prefix in a hash
|
||||
* table. Passes ownership to caller.
|
||||
* Returns a key that can be used to lookup the IP Prefix in a hash table.
|
||||
*/
|
||||
std::unique_ptr<HashKey> MakeHashKey() const;
|
||||
|
||||
[[deprecated("Remove in v4.1. Use MakeHashKey().")]]
|
||||
HashKey* GetHashKey() const;
|
||||
|
||||
/** Converts the prefix into the type used internally by the
|
||||
|
|
|
@ -739,16 +739,14 @@ bool BloomFilterVal::Typify(IntrusivePtr<BroType> arg_type)
|
|||
|
||||
void BloomFilterVal::Add(const Val* val)
|
||||
{
|
||||
HashKey* key = hash->ComputeHash(*val, true);
|
||||
bloom_filter->Add(key);
|
||||
delete key;
|
||||
auto key = hash->MakeHashKey(*val, true);
|
||||
bloom_filter->Add(key.get());
|
||||
}
|
||||
|
||||
size_t BloomFilterVal::Count(const Val* val) const
|
||||
{
|
||||
HashKey* key = hash->ComputeHash(*val, true);
|
||||
size_t cnt = bloom_filter->Count(key);
|
||||
delete key;
|
||||
auto key = hash->MakeHashKey(*val, true);
|
||||
size_t cnt = bloom_filter->Count(key.get());
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
@ -900,9 +898,8 @@ bool CardinalityVal::Typify(IntrusivePtr<BroType> arg_type)
|
|||
|
||||
void CardinalityVal::Add(const Val* val)
|
||||
{
|
||||
HashKey* key = hash->ComputeHash(*val, true);
|
||||
auto key = hash->MakeHashKey(*val, true);
|
||||
c->AddElement(key->Hash());
|
||||
delete key;
|
||||
}
|
||||
|
||||
IMPLEMENT_OPAQUE_VALUE(CardinalityVal)
|
||||
|
|
|
@ -78,7 +78,7 @@ void Reporter::InitOptions()
|
|||
|
||||
while ( (v = wl_table->NextEntry(k, c)) )
|
||||
{
|
||||
auto index = wl_val->RecoverIndex(k);
|
||||
auto index = wl_val->RecreateIndex(*k);
|
||||
std::string key = index->Idx(0)->AsString()->CheckString();
|
||||
weird_sampling_whitelist.emplace(move(key));
|
||||
delete k;
|
||||
|
|
18
src/Stmt.cc
18
src/Stmt.cc
|
@ -719,7 +719,7 @@ SwitchStmt::~SwitchStmt()
|
|||
|
||||
bool SwitchStmt::AddCaseLabelValueMapping(const Val* v, int idx)
|
||||
{
|
||||
HashKey* hk = comp_hash->ComputeHash(*v, true);
|
||||
auto hk = comp_hash->MakeHashKey(*v, true);
|
||||
|
||||
if ( ! hk )
|
||||
{
|
||||
|
@ -728,16 +728,12 @@ bool SwitchStmt::AddCaseLabelValueMapping(const Val* v, int idx)
|
|||
type_name(v->GetType()->Tag()), type_name(e->GetType()->Tag()));
|
||||
}
|
||||
|
||||
int* label_idx = case_label_value_map.Lookup(hk);
|
||||
int* label_idx = case_label_value_map.Lookup(hk.get());
|
||||
|
||||
if ( label_idx )
|
||||
{
|
||||
delete hk;
|
||||
return false;
|
||||
}
|
||||
|
||||
case_label_value_map.Insert(hk, new int(idx));
|
||||
delete hk;
|
||||
case_label_value_map.Insert(hk.get(), new int(idx));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -763,7 +759,7 @@ std::pair<int, ID*> SwitchStmt::FindCaseLabelMatch(const Val* v) const
|
|||
// Find matching expression cases.
|
||||
if ( case_label_value_map.Length() )
|
||||
{
|
||||
HashKey* hk = comp_hash->ComputeHash(*v, true);
|
||||
auto hk = comp_hash->MakeHashKey(*v, true);
|
||||
|
||||
if ( ! hk )
|
||||
{
|
||||
|
@ -773,10 +769,8 @@ std::pair<int, ID*> SwitchStmt::FindCaseLabelMatch(const Val* v) const
|
|||
return std::make_pair(-1, nullptr);
|
||||
}
|
||||
|
||||
if ( auto i = case_label_value_map.Lookup(hk) )
|
||||
if ( auto i = case_label_value_map.Lookup(hk.get()) )
|
||||
label_idx = *i;
|
||||
|
||||
delete hk;
|
||||
}
|
||||
|
||||
// Find matching type cases.
|
||||
|
@ -1193,7 +1187,7 @@ IntrusivePtr<Val> ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
|
|||
IterCookie* c = loop_vals->InitForIteration();
|
||||
while ( (current_tev = loop_vals->NextEntry(k, c)) )
|
||||
{
|
||||
auto ind_lv = tv->RecoverIndex(k);
|
||||
auto ind_lv = tv->RecreateIndex(*k);
|
||||
delete k;
|
||||
|
||||
if ( value_var )
|
||||
|
|
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;
|
||||
}
|
||||
|
||||
|
|
35
src/Val.h
35
src/Val.h
|
@ -761,13 +761,13 @@ public:
|
|||
* case of a set, just adds the index).
|
||||
* @param index The key to assign. For tables, this is allowed to be null
|
||||
* (if needed, the index val can be recovered from the hash key).
|
||||
* @param k A precomputed hash key to use (this method takes ownership
|
||||
* of deleting it).
|
||||
* @param k A precomputed hash key to use.
|
||||
* @param new_val The value to assign at the index. For a set, this
|
||||
* must be nullptr.
|
||||
* @return True if the assignment type-checked.
|
||||
*/
|
||||
bool Assign(IntrusivePtr<Val> index, HashKey* k, IntrusivePtr<Val> new_val);
|
||||
bool Assign(IntrusivePtr<Val> index, std::unique_ptr<HashKey> k,
|
||||
IntrusivePtr<Val> new_val);
|
||||
|
||||
// Returns true if the assignment typechecked, false if not. The
|
||||
// methods take ownership of new_val, but not of the index. If we're
|
||||
|
@ -877,8 +877,14 @@ public:
|
|||
// Returns false if index does not exist.
|
||||
bool UpdateTimestamp(Val* index);
|
||||
|
||||
// Returns the index corresponding to the given HashKey.
|
||||
IntrusivePtr<ListVal> RecoverIndex(const HashKey* k) const;
|
||||
/**
|
||||
* @return The index corresponding to the given HashKey.
|
||||
*/
|
||||
IntrusivePtr<ListVal> RecreateIndex(const HashKey& k) const;
|
||||
|
||||
[[deprecated("Remove in v4.1. Use RecreateIndex().")]]
|
||||
ListVal* RecoverIndex(const HashKey* k) const
|
||||
{ return RecreateIndex(*k).release(); }
|
||||
|
||||
/**
|
||||
* Remove an element from the table and return it.
|
||||
|
@ -892,11 +898,10 @@ public:
|
|||
|
||||
/**
|
||||
* Same as Remove(const Val&), but uses a precomputed hash key.
|
||||
* @param k The hash key to lookup. This method takes ownership of
|
||||
* deleting it.
|
||||
* @param k The hash key to lookup.
|
||||
* @return Same as Remove(const Val&).
|
||||
*/
|
||||
IntrusivePtr<Val> Remove(const HashKey* k);
|
||||
IntrusivePtr<Val> Remove(const HashKey& k);
|
||||
|
||||
[[deprecated("Remove in v4.1. Use Remove().")]]
|
||||
Val* Delete(const Val* index)
|
||||
|
@ -904,7 +909,7 @@ public:
|
|||
|
||||
[[deprecated("Remove in v4.1. Use Remove().")]]
|
||||
Val* Delete(const HashKey* k)
|
||||
{ return Remove(k).release(); }
|
||||
{ return Remove(*k).release(); }
|
||||
|
||||
// Returns a ListVal representation of the table (which must be a set).
|
||||
IntrusivePtr<ListVal> ToListVal(TypeTag t = TYPE_ANY) const;
|
||||
|
@ -954,11 +959,15 @@ public:
|
|||
timer = nullptr;
|
||||
}
|
||||
|
||||
HashKey* ComputeHash(const Val& index) const;
|
||||
/**
|
||||
* @param The index value to hash.
|
||||
* @return The hash of the index value or nullptr if
|
||||
* type-checking failed.
|
||||
*/
|
||||
std::unique_ptr<HashKey> MakeHashKey(const Val& index) const;
|
||||
|
||||
[[deprecated("Remove in v4.1. Pass a Val& instead.")]]
|
||||
HashKey* ComputeHash(const Val* index) const
|
||||
{ return ComputeHash(*index); }
|
||||
[[deprecated("Remove in v4.1. Use MakeHashKey().")]]
|
||||
HashKey* ComputeHash(const Val* index) const;
|
||||
|
||||
notifier::Modifiable* Modifiable() override { return this; }
|
||||
|
||||
|
|
|
@ -901,7 +901,7 @@ broker::expected<broker::data> bro_broker::val_to_data(const Val* v)
|
|||
|
||||
while ( (entry = table->NextEntry(hk, c)) )
|
||||
{
|
||||
auto vl = table_val->RecoverIndex(hk);
|
||||
auto vl = table_val->RecreateIndex(*hk);
|
||||
delete hk;
|
||||
|
||||
broker::vector composite_key;
|
||||
|
|
|
@ -38,7 +38,7 @@ std::set<std::string> val_to_topic_set(Val* val)
|
|||
|
||||
while ( tbl->NextEntry(k, c) )
|
||||
{
|
||||
auto index = val->AsTableVal()->RecoverIndex(k);
|
||||
auto index = val->AsTableVal()->RecreateIndex(*k);
|
||||
rval.emplace(index->Idx(0)->AsString()->CheckString());
|
||||
delete k;
|
||||
}
|
||||
|
|
|
@ -166,12 +166,12 @@ HashKey* AnalyzerSet::GetKey(const file_analysis::Tag& t, RecordVal* args) const
|
|||
auto lv = make_intrusive<ListVal>(TYPE_ANY);
|
||||
lv->Append(t.AsVal());
|
||||
lv->Append({NewRef{}, args});
|
||||
HashKey* key = analyzer_hash->ComputeHash(*lv, true);
|
||||
auto key = analyzer_hash->MakeHashKey(*lv, true);
|
||||
|
||||
if ( ! key )
|
||||
reporter->InternalError("AnalyzerArgs type mismatch");
|
||||
|
||||
return key;
|
||||
return key.release();
|
||||
}
|
||||
|
||||
file_analysis::Analyzer* AnalyzerSet::InstantiateAnalyzer(const Tag& tag,
|
||||
|
|
|
@ -285,7 +285,7 @@ bool Manager::CreateStream(Stream* info, RecordVal* description)
|
|||
TableEntryVal* v;
|
||||
while ( (v = info->config->AsTable()->NextEntry(k, c)) )
|
||||
{
|
||||
auto index = info->config->RecoverIndex(k);
|
||||
auto index = info->config->RecreateIndex(*k);
|
||||
string key = index->Idx(0)->AsString()->CheckString();
|
||||
string value = v->GetVal()->AsString()->CheckString();
|
||||
rinfo.config.insert(std::make_pair(copy_string(key.c_str()), copy_string(value.c_str())));
|
||||
|
@ -1248,7 +1248,8 @@ int Manager::SendEntryTable(Stream* i, const Value* const *vals)
|
|||
oldval = stream->tab->Find({NewRef{}, idxval});
|
||||
}
|
||||
|
||||
HashKey* k = stream->tab->ComputeHash(*idxval);
|
||||
auto k = stream->tab->MakeHashKey(*idxval);
|
||||
|
||||
if ( ! k )
|
||||
reporter->InternalError("could not hash");
|
||||
|
||||
|
@ -1256,7 +1257,7 @@ int Manager::SendEntryTable(Stream* i, const Value* const *vals)
|
|||
ih->idxkey = new HashKey(k->Key(), k->Size(), k->Hash());
|
||||
ih->valhash = valhash;
|
||||
|
||||
stream->tab->Assign({AdoptRef{}, idxval}, k, {AdoptRef{}, valval});
|
||||
stream->tab->Assign({AdoptRef{}, idxval}, std::move(k), {AdoptRef{}, valval});
|
||||
|
||||
if ( predidx != nullptr )
|
||||
Unref(predidx);
|
||||
|
@ -1342,7 +1343,7 @@ void Manager::EndCurrentSend(ReaderFrontend* reader)
|
|||
|
||||
if ( stream->pred || stream->event )
|
||||
{
|
||||
auto idx = stream->tab->RecoverIndex(ih->idxkey);
|
||||
auto idx = stream->tab->RecreateIndex(*ih->idxkey);
|
||||
assert(idx != nullptr);
|
||||
val = stream->tab->FindOrDefault(idx);
|
||||
assert(val != nullptr);
|
||||
|
@ -1371,7 +1372,7 @@ void Manager::EndCurrentSend(ReaderFrontend* reader)
|
|||
SendEvent(stream->event, 4, stream->description->Ref(), ev->Ref(),
|
||||
predidx->Ref(), val->Ref());
|
||||
|
||||
stream->tab->Remove(ih->idxkey);
|
||||
stream->tab->Remove(*ih->idxkey);
|
||||
stream->lastDict->Remove(lastDictIdxKey); // delete in next line
|
||||
delete lastDictIdxKey;
|
||||
delete(ih);
|
||||
|
|
|
@ -865,7 +865,7 @@ bool Manager::Write(EnumVal* id, RecordVal* columns_arg)
|
|||
TableEntryVal* v;
|
||||
while ( (v = filter->config->AsTable()->NextEntry(k, c)) )
|
||||
{
|
||||
auto index = filter->config->RecoverIndex(k);
|
||||
auto index = filter->config->RecreateIndex(*k);
|
||||
string key = index->Idx(0)->AsString()->CheckString();
|
||||
string value = v->GetVal()->AsString()->CheckString();
|
||||
info->config.insert(std::make_pair(copy_string(key.c_str()), copy_string(value.c_str())));
|
||||
|
|
|
@ -29,9 +29,9 @@ void TopkVal::Typify(IntrusivePtr<BroType> t)
|
|||
|
||||
HashKey* TopkVal::GetHash(Val* v) const
|
||||
{
|
||||
HashKey* key = hash->ComputeHash(*v, true);
|
||||
auto key = hash->MakeHashKey(*v, true);
|
||||
assert(key);
|
||||
return key;
|
||||
return key.release();
|
||||
}
|
||||
|
||||
TopkVal::TopkVal(uint64_t arg_size) : OpaqueVal(topk_type)
|
||||
|
|
|
@ -179,7 +179,7 @@ function Reporter::set_weird_sampling_whitelist%(weird_sampling_whitelist: strin
|
|||
|
||||
while ( (v = wl_table->NextEntry(k, c)) )
|
||||
{
|
||||
auto index = wl_val->RecoverIndex(k);
|
||||
auto index = wl_val->RecreateIndex(*k);
|
||||
string key = index->Idx(0)->AsString()->CheckString();
|
||||
whitelist_set.emplace(move(key));
|
||||
delete k;
|
||||
|
|
|
@ -1024,7 +1024,7 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node)
|
|||
|
||||
while ( (v = cluster_table->NextEntry(k, c)) )
|
||||
{
|
||||
auto key = cluster_table_val->RecoverIndex(k);
|
||||
auto key = cluster_table_val->RecreateIndex(*k);
|
||||
delete k;
|
||||
auto name = key->Idx(0)->AsStringVal()->ToStdString();
|
||||
auto rv = v->GetVal()->AsRecordVal();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue