Remove most of MutableVal (but not the class itelf yet)

This commit is contained in:
Robin Sommer 2019-06-06 03:28:12 +00:00
parent 0ba382280c
commit f8262b65c4
3 changed files with 7 additions and 343 deletions

View file

@ -155,16 +155,6 @@ void ID::UpdateValAttrs()
if ( ! attrs )
return;
MutableVal::Properties props = 0;
if ( val && val->IsMutableVal() )
{
if ( attrs->FindAttr(ATTR_TRACKED) )
props |= MutableVal::TRACKED;
val->AsMutableVal()->AddProperties(props);
}
if ( val && val->Type()->Tag() == TYPE_TABLE )
val->AsTableVal()->SetAttrs(attrs);
@ -222,16 +212,6 @@ void ID::RemoveAttr(attr_tag a)
{
if ( attrs )
attrs->RemoveAttr(a);
if ( val && val->IsMutableVal() )
{
MutableVal::Properties props = 0;
if ( a == ATTR_TRACKED )
props |= MutableVal::TRACKED;
val->AsMutableVal()->RemoveProperties(props);
}
}
void ID::SetOption()

View file

@ -351,120 +351,6 @@ void Val::ValDescribeReST(ODesc* d) const
MutableVal::~MutableVal()
{
for ( list<ID*>::iterator i = aliases.begin(); i != aliases.end(); ++i )
{
if ( global_scope() )
global_scope()->Remove((*i)->Name());
(*i)->ClearVal(); // just to make sure.
Unref((*i));
}
if ( id )
{
if ( global_scope() )
global_scope()->Remove(id->Name());
id->ClearVal(); // just to make sure.
Unref(id);
}
}
bool MutableVal::AddProperties(Properties arg_props)
{
if ( (props | arg_props) == props )
// No change.
return false;
props |= arg_props;
if ( ! id )
Bind();
return true;
}
bool MutableVal::RemoveProperties(Properties arg_props)
{
if ( (props & ~arg_props) == props )
// No change.
return false;
props &= ~arg_props;
return true;
}
ID* MutableVal::Bind() const
{
static bool initialized = false;
assert(!id);
static unsigned int id_counter = 0;
static const int MAX_NAME_SIZE = 128;
static char name[MAX_NAME_SIZE];
static char* end_of_static_str = 0;
if ( ! initialized )
{
// Get local IP.
char host[MAXHOSTNAMELEN];
strcpy(host, "localhost");
gethostname(host, MAXHOSTNAMELEN);
host[MAXHOSTNAMELEN-1] = '\0';
#if 0
// We ignore errors.
struct hostent* ent = gethostbyname(host);
uint32 ip;
if ( ent && ent->h_addr_list[0] )
ip = *(uint32*) ent->h_addr_list[0];
else
ip = htonl(0x7f000001); // 127.0.0.1
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#",
IPAddr(IPv4, &ip, IPAddr::Network)->AsString().c_str(),
getpid());
#else
safe_snprintf(name, MAX_NAME_SIZE, "#%s#%d#", host, getpid());
#endif
end_of_static_str = name + strlen(name);
initialized = true;
}
safe_snprintf(end_of_static_str, MAX_NAME_SIZE - (end_of_static_str - name),
"%u", ++id_counter);
name[MAX_NAME_SIZE-1] = '\0';
id = new ID(name, SCOPE_GLOBAL, true);
id->SetType(const_cast<MutableVal*>(this)->Type()->Ref());
global_scope()->Insert(name, id);
id->SetVal(const_cast<MutableVal*>(this), true);
return id;
}
void MutableVal::TransferUniqueID(MutableVal* mv)
{
const char* new_name = mv->UniqueID()->Name();
if ( ! id )
Bind();
// Keep old name as alias.
aliases.push_back(id);
id = new ID(new_name, SCOPE_GLOBAL, true);
id->SetType(const_cast<MutableVal*>(this)->Type()->Ref());
global_scope()->Insert(new_name, id);
id->SetVal(const_cast<MutableVal*>(this), true);
Unref(mv->id);
mv->id = 0;
}
IntervalVal::IntervalVal(double quantity, double units) :
@ -2026,23 +1912,6 @@ double TableVal::CallExpireFunc(Val* idx)
return secs;
}
void TableVal::ReadOperation(Val* index, TableEntryVal* v)
{
double timeout = GetExpireTime();
if ( timeout < 0 )
// Skip in case of unset/invalid expiration value. If it's an
// error, it has been reported already.
return;
// In theory we need to only propagate one update per &read_expire
// interval to prevent peers from expiring intervals. To account for
// practical issues such as latency, we send one update every half
// &read_expire.
if ( network_time - v->LastReadUpdate() > timeout / 2 )
v->SetLastReadUpdate(network_time);
}
Val* TableVal::DoClone(CloneState* state)
{
auto tv = new TableVal(table_type);
@ -2092,48 +1961,6 @@ Val* TableVal::DoClone(CloneState* state)
return tv;
}
bool TableVal::AddProperties(Properties arg_props)
{
if ( ! MutableVal::AddProperties(arg_props) )
return false;
if ( Type()->IsSet() || ! RecursiveProps(arg_props) )
return true;
// For a large table, this could get expensive. So, let's hope
// that nobody creates such a table *before* making it persistent
// (for example by inserting it into another table).
TableEntryVal* v;
PDict(TableEntryVal)* tbl = val.table_val;
IterCookie* c = tbl->InitForIteration();
while ( (v = tbl->NextEntry(c)) )
if ( v->Value()->IsMutableVal() )
v->Value()->AsMutableVal()->AddProperties(RecursiveProps(arg_props));
return true;
}
bool TableVal::RemoveProperties(Properties arg_props)
{
if ( ! MutableVal::RemoveProperties(arg_props) )
return false;
if ( Type()->IsSet() || ! RecursiveProps(arg_props) )
return true;
// For a large table, this could get expensive. So, let's hope
// that nobody creates such a table *before* making it persistent
// (for example by inserting it into another table).
TableEntryVal* v;
PDict(TableEntryVal)* tbl = val.table_val;
IterCookie* c = tbl->InitForIteration();
while ( (v = tbl->NextEntry(c)) )
if ( v->Value()->IsMutableVal() )
v->Value()->AsMutableVal()->RemoveProperties(RecursiveProps(arg_props));
return true;
}
unsigned int TableVal::MemoryAllocation() const
{
unsigned int size = 0;
@ -2428,41 +2255,6 @@ Val* RecordVal::DoClone(CloneState* state)
return rv;
}
bool RecordVal::AddProperties(Properties arg_props)
{
if ( ! MutableVal::AddProperties(arg_props) )
return false;
if ( ! RecursiveProps(arg_props) )
return true;
loop_over_list(*val.val_list_val, i)
{
Val* v = (*val.val_list_val)[i];
if ( v && v->IsMutableVal() )
v->AsMutableVal()->AddProperties(RecursiveProps(arg_props));
}
return true;
}
bool RecordVal::RemoveProperties(Properties arg_props)
{
if ( ! MutableVal::RemoveProperties(arg_props) )
return false;
if ( ! RecursiveProps(arg_props) )
return true;
loop_over_list(*val.val_list_val, i)
{
Val* v = (*val.val_list_val)[i];
if ( v && v->IsMutableVal() )
v->AsMutableVal()->RemoveProperties(RecursiveProps(arg_props));
}
return true;
}
unsigned int RecordVal::MemoryAllocation() const
{
unsigned int size = 0;
@ -2599,37 +2391,6 @@ unsigned int VectorVal::ResizeAtLeast(unsigned int new_num_elements)
return Resize(new_num_elements);
}
bool VectorVal::AddProperties(Properties arg_props)
{
if ( ! MutableVal::AddProperties(arg_props) )
return false;
if ( ! RecursiveProps(arg_props) )
return true;
for ( unsigned int i = 0; i < val.vector_val->size(); ++i )
if ( (*val.vector_val)[i]->IsMutableVal() )
(*val.vector_val)[i]->AsMutableVal()->AddProperties(RecursiveProps(arg_props));
return true;
}
bool VectorVal::RemoveProperties(Properties arg_props)
{
if ( ! MutableVal::RemoveProperties(arg_props) )
return false;
if ( ! RecursiveProps(arg_props) )
return true;
for ( unsigned int i = 0; i < val.vector_val->size(); ++i )
if ( (*val.vector_val)[i]->IsMutableVal() )
(*val.vector_val)[i]->AsMutableVal()->RemoveProperties(RecursiveProps(arg_props));
return true;
}
Val* VectorVal::DoClone(CloneState* state)
{
auto vv = new VectorVal(vector_type);

View file

@ -325,20 +325,6 @@ public:
return IsMutable(type->Tag());
}
const MutableVal* AsMutableVal() const
{
if ( ! IsMutableVal() )
BadTag("Val::AsMutableVal", type_name(type->Tag()));
return (MutableVal*) this;
}
MutableVal* AsMutableVal()
{
if ( ! IsMutableVal() )
BadTag("Val::AsMutableVal", type_name(type->Tag()));
return (MutableVal*) this;
}
void Describe(ODesc* d) const override;
virtual void DescribeReST(ODesc* d) const;
@ -499,56 +485,13 @@ private:
extern ValManager* val_mgr;
class MutableVal : public Val {
public:
// Each MutableVal gets a globally unique ID that can be used to
// reference it no matter if it's directly bound to any user-visible
// ID. This ID is inserted into the global namespace.
ID* UniqueID() const { return id ? id : Bind(); }
// Returns true if we've already generated a unique ID.
bool HasUniqueID() const { return id; }
// Transfers the unique ID of the given value to this value. We keep our
// old ID as an alias.
void TransferUniqueID(MutableVal* mv);
// MutableVals can have properties (let's refrain from calling them
// attributes!). Most properties are recursive. If a derived object
// can contain MutableVals itself, the object has to override
// {Add,Remove}Properties(). RecursiveProp(state) masks out all non-
// recursive properties. If this is non-null, an overriden method must
// call itself with RecursiveProp(state) as argument for all contained
// values. (In any case, don't forget to call the parent's method.)
typedef char Properties;
// Tracked by NotifierRegistry, not recursive.
static const int TRACKED = 0x04;
int RecursiveProps(int prop) const { return prop & ~TRACKED; }
Properties GetProperties() const { return props; }
virtual bool AddProperties(Properties state);
virtual bool RemoveProperties(Properties state);
protected:
explicit MutableVal(BroType* t) : Val(t)
{ props = 0; id = 0; }
MutableVal() { props = 0; id = 0; }
explicit MutableVal(BroType* t) : Val(t) {}
MutableVal() {}
~MutableVal() override;
friend class ID;
friend class Val;
void SetID(ID* arg_id) { Unref(id); id = arg_id; }
void Modified() { notifiers.Modified(this); }
private:
ID* Bind() const;
mutable ID* id;
list<ID*> aliases;
Properties props;
uint64 last_modified;
};
#define Microseconds 1e-6
@ -771,7 +714,7 @@ public:
{
val = v;
last_access_time = network_time;
expire_access_time = last_read_update =
expire_access_time =
int(network_time - bro_start_network_time);
}
@ -780,7 +723,6 @@ public:
auto rval = new TableEntryVal(val ? val->Clone() : nullptr);
rval->last_access_time = last_access_time;
rval->expire_access_time = expire_access_time;
rval->last_read_update = last_read_update;
return rval;
}
@ -796,24 +738,16 @@ public:
void SetExpireAccess(double time)
{ expire_access_time = int(time - bro_start_network_time); }
// Returns/sets time of when we propagated the last OP_READ_IDX
// for this item.
double LastReadUpdate() const
{ return bro_start_network_time + last_read_update; }
void SetLastReadUpdate(double time)
{ last_read_update = int(time - bro_start_network_time); }
protected:
friend class TableVal;
Val* val;
double last_access_time;
// The next two entries store seconds since Bro's start. We use
// ints here to save a few bytes, as we do not need a high resolution
// for these anyway.
// The next entry stores seconds since Bro's start. We use ints here
// to save a few bytes, as we do not need a high resolution for these
// anyway.
int expire_access_time;
int last_read_update;
};
class TableValTimer : public Timer {
@ -953,9 +887,6 @@ protected:
int ExpandCompoundAndInit(val_list* vl, int k, Val* new_val);
int CheckAndAssign(Val* index, Val* new_val);
bool AddProperties(Properties arg_state) override;
bool RemoveProperties(Properties arg_state) override;
// Calculates default value for index. Returns 0 if none.
Val* Default(Val* index);
@ -971,9 +902,6 @@ protected:
// takes ownership of the reference.
double CallExpireFunc(Val *idx);
// Propagates a read operation if necessary.
void ReadOperation(Val* index, TableEntryVal *v);
Val* DoClone(CloneState* state) override;
TableType* table_type;
@ -1043,9 +971,6 @@ protected:
friend class Val;
RecordVal() {}
bool AddProperties(Properties arg_state) override;
bool RemoveProperties(Properties arg_state) override;
Val* DoClone(CloneState* state) override;
RecordType* record_type;
@ -1133,8 +1058,6 @@ protected:
friend class Val;
VectorVal() { }
bool AddProperties(Properties arg_state) override;
bool RemoveProperties(Properties arg_state) override;
void ValDescribe(ODesc* d) const override;
Val* DoClone(CloneState* state) override;