mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00
convert VectorVal's to use vector<ZVal> as internal representation
This commit is contained in:
parent
6121e409d3
commit
0299ea0894
3 changed files with 138 additions and 26 deletions
135
src/Val.cc
135
src/Val.cc
|
@ -3177,14 +3177,19 @@ ValPtr TypeVal::DoClone(CloneState* state)
|
||||||
return {NewRef{}, this};
|
return {NewRef{}, this};
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorVal::VectorVal(VectorTypePtr t) : Val(std::move(t))
|
VectorVal::VectorVal(VectorTypePtr t) : Val(t)
|
||||||
{
|
{
|
||||||
vector_val = new vector<ValPtr>();
|
vector_val = new vector<ZVal>();
|
||||||
|
yield_type = t->Yield();
|
||||||
|
|
||||||
|
auto y_tag = yield_type->Tag();
|
||||||
|
any_yield = (y_tag == TYPE_VOID || y_tag == TYPE_ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorVal::~VectorVal()
|
VectorVal::~VectorVal()
|
||||||
{
|
{
|
||||||
delete vector_val;
|
delete vector_val;
|
||||||
|
delete yield_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValPtr VectorVal::SizeVal() const
|
ValPtr VectorVal::SizeVal() const
|
||||||
|
@ -3192,16 +3197,64 @@ ValPtr VectorVal::SizeVal() const
|
||||||
return val_mgr->Count(uint32_t(vector_val->size()));
|
return val_mgr->Count(uint32_t(vector_val->size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VectorVal::CheckElementType(const ValPtr& element)
|
||||||
|
{
|
||||||
|
if ( ! element )
|
||||||
|
// Insertion isn't actually going to happen.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( yield_types )
|
||||||
|
// We're already a heterogeneous vector-of-any.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( any_yield )
|
||||||
|
{
|
||||||
|
auto n = vector_val->size();
|
||||||
|
|
||||||
|
if ( n == 0 )
|
||||||
|
// First addition to an empty vector-of-any, perhaps
|
||||||
|
// it will be homogeneous.
|
||||||
|
yield_type = element->GetType();
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yield_types = new std::vector<TypePtr>();
|
||||||
|
|
||||||
|
// Since we're only now switching to the heterogeneous
|
||||||
|
// representation, capture the types of the existing
|
||||||
|
// elements.
|
||||||
|
|
||||||
|
for ( auto i = 0; i < n; ++i )
|
||||||
|
yield_types->emplace_back(yield_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ( ! same_type(element->GetType(), yield_type, false) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool VectorVal::Assign(unsigned int index, ValPtr element)
|
bool VectorVal::Assign(unsigned int index, ValPtr element)
|
||||||
{
|
{
|
||||||
if ( element &&
|
if ( ! CheckElementType(element) )
|
||||||
! same_type(element->GetType(), GetType()->AsVectorType()->Yield(), false) )
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( index >= vector_val->size() )
|
if ( index >= vector_val->size() )
|
||||||
|
{
|
||||||
vector_val->resize(index + 1);
|
vector_val->resize(index + 1);
|
||||||
|
if ( yield_types )
|
||||||
|
yield_types->resize(index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
(*vector_val)[index] = std::move(element);
|
if ( yield_types )
|
||||||
|
{
|
||||||
|
const auto& t = element->GetType();
|
||||||
|
(*yield_types)[index] = t;
|
||||||
|
(*vector_val)[index] = ZVal(std::move(element), t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
(*vector_val)[index] = ZVal(std::move(element), yield_type);
|
||||||
|
|
||||||
Modified();
|
Modified();
|
||||||
return true;
|
return true;
|
||||||
|
@ -3221,20 +3274,33 @@ bool VectorVal::AssignRepeat(unsigned int index, unsigned int how_many,
|
||||||
|
|
||||||
bool VectorVal::Insert(unsigned int index, ValPtr element)
|
bool VectorVal::Insert(unsigned int index, ValPtr element)
|
||||||
{
|
{
|
||||||
if ( element &&
|
if ( ! CheckElementType(element) )
|
||||||
! same_type(element->GetType(), GetType()->AsVectorType()->Yield(), false) )
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
vector<ValPtr>::iterator it;
|
vector<ZVal>::iterator it;
|
||||||
|
vector<TypePtr>::iterator types_it;
|
||||||
|
|
||||||
if ( index < vector_val->size() )
|
if ( index < vector_val->size() )
|
||||||
|
{
|
||||||
it = std::next(vector_val->begin(), index);
|
it = std::next(vector_val->begin(), index);
|
||||||
|
if ( yield_types )
|
||||||
|
types_it = std::next(yield_types->begin(), index);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
it = vector_val->end();
|
it = vector_val->end();
|
||||||
|
if ( yield_types )
|
||||||
|
types_it = yield_types->end();
|
||||||
|
}
|
||||||
|
|
||||||
vector_val->insert(it, std::move(element));
|
if ( yield_types )
|
||||||
|
{
|
||||||
|
const auto& t = element->GetType();
|
||||||
|
yield_types->insert(types_it, element->GetType());
|
||||||
|
vector_val->insert(it, ZVal(std::move(element), t));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vector_val->insert(it, ZVal(std::move(element), yield_type));
|
||||||
|
|
||||||
Modified();
|
Modified();
|
||||||
return true;
|
return true;
|
||||||
|
@ -3248,6 +3314,12 @@ bool VectorVal::Remove(unsigned int index)
|
||||||
auto it = std::next(vector_val->begin(), index);
|
auto it = std::next(vector_val->begin(), index);
|
||||||
vector_val->erase(it);
|
vector_val->erase(it);
|
||||||
|
|
||||||
|
if ( yield_types )
|
||||||
|
{
|
||||||
|
auto types_it = std::next(yield_types->begin(), index);
|
||||||
|
yield_types->erase(types_it);
|
||||||
|
}
|
||||||
|
|
||||||
Modified();
|
Modified();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3276,17 +3348,19 @@ bool VectorVal::AddTo(Val* val, bool /* is_first_init */) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ValPtr& VectorVal::At(unsigned int index) const
|
ValPtr VectorVal::At(unsigned int index) const
|
||||||
{
|
{
|
||||||
if ( index >= vector_val->size() )
|
if ( index >= vector_val->size() )
|
||||||
return Val::nil;
|
return Val::nil;
|
||||||
|
|
||||||
return (*vector_val)[index];
|
const auto& t = yield_types ? (*yield_types)[index] : yield_type;
|
||||||
|
|
||||||
|
return (*vector_val)[index].ToVal(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VectorVal::Sort(bool cmp_func(const ValPtr& a, const ValPtr& b))
|
void VectorVal::Sort(bool cmp_func(const ValPtr& a, const ValPtr& b))
|
||||||
{
|
{
|
||||||
sort(vector_val->begin(), vector_val->end(), cmp_func);
|
// Placeholder - will be filled in by a later commit.
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int VectorVal::Resize(unsigned int new_num_elements)
|
unsigned int VectorVal::Resize(unsigned int new_num_elements)
|
||||||
|
@ -3294,6 +3368,13 @@ unsigned int VectorVal::Resize(unsigned int new_num_elements)
|
||||||
unsigned int oldsize = vector_val->size();
|
unsigned int oldsize = vector_val->size();
|
||||||
vector_val->reserve(new_num_elements);
|
vector_val->reserve(new_num_elements);
|
||||||
vector_val->resize(new_num_elements);
|
vector_val->resize(new_num_elements);
|
||||||
|
|
||||||
|
if ( yield_types )
|
||||||
|
{
|
||||||
|
yield_types->reserve(new_num_elements);
|
||||||
|
yield_types->resize(new_num_elements);
|
||||||
|
}
|
||||||
|
|
||||||
return oldsize;
|
return oldsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3309,6 +3390,9 @@ unsigned int VectorVal::ResizeAtLeast(unsigned int new_num_elements)
|
||||||
void VectorVal::Reserve(unsigned int num_elements)
|
void VectorVal::Reserve(unsigned int num_elements)
|
||||||
{
|
{
|
||||||
vector_val->reserve(num_elements);
|
vector_val->reserve(num_elements);
|
||||||
|
|
||||||
|
if ( yield_types )
|
||||||
|
yield_types->reserve(num_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
ValPtr VectorVal::DoClone(CloneState* state)
|
ValPtr VectorVal::DoClone(CloneState* state)
|
||||||
|
@ -3317,9 +3401,11 @@ ValPtr VectorVal::DoClone(CloneState* state)
|
||||||
vv->Reserve(vector_val->size());
|
vv->Reserve(vector_val->size());
|
||||||
state->NewClone(this, vv);
|
state->NewClone(this, vv);
|
||||||
|
|
||||||
for ( const auto& e : *vector_val )
|
auto n = vector_val->size();
|
||||||
|
|
||||||
|
for ( auto i = 0; i < n; ++i )
|
||||||
{
|
{
|
||||||
auto vc = e->Clone(state);
|
auto vc = At(i)->Clone(state);
|
||||||
vv->Append(std::move(vc));
|
vv->Append(std::move(vc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3332,18 +3418,21 @@ void VectorVal::ValDescribe(ODesc* d) const
|
||||||
|
|
||||||
size_t vector_size = vector_val->size();
|
size_t vector_size = vector_val->size();
|
||||||
|
|
||||||
if ( vector_size != 0)
|
if ( vector_size != 0 )
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < (vector_size - 1); ++i )
|
auto last_ind = vector_size - 1;
|
||||||
|
for ( unsigned int i = 0; i < last_ind; ++i )
|
||||||
{
|
{
|
||||||
if ( vector_val->at(i) )
|
auto v = At(i);
|
||||||
vector_val->at(i)->Describe(d);
|
if ( v )
|
||||||
|
v->Describe(d);
|
||||||
d->Add(", ");
|
d->Add(", ");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ( vector_size != 0 && vector_val->back() )
|
auto v = At(last_ind);
|
||||||
vector_val->back()->Describe(d);
|
if ( v )
|
||||||
|
v->Describe(d);
|
||||||
|
}
|
||||||
|
|
||||||
d->Add("]");
|
d->Add("]");
|
||||||
}
|
}
|
||||||
|
|
26
src/Val.h
26
src/Val.h
|
@ -1305,7 +1305,7 @@ public:
|
||||||
* @return The element at the given index or nullptr if the index
|
* @return The element at the given index or nullptr if the index
|
||||||
* does not exist (it's greater than or equal to vector's current size).
|
* does not exist (it's greater than or equal to vector's current size).
|
||||||
*/
|
*/
|
||||||
const ValPtr& At(unsigned int index) const;
|
ValPtr At(unsigned int index) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the given element treated as a Count type, to efficiently
|
* Returns the given element treated as a Count type, to efficiently
|
||||||
|
@ -1364,7 +1364,29 @@ protected:
|
||||||
ValPtr DoClone(CloneState* state) override;
|
ValPtr DoClone(CloneState* state) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<ValPtr>* vector_val;
|
// Check the type of the given element against our current
|
||||||
|
// yield type and adjust as necessary. Returns whether the
|
||||||
|
// element type-checked.
|
||||||
|
bool CheckElementType(const ValPtr& element);
|
||||||
|
|
||||||
|
std::vector<ZVal>* vector_val;
|
||||||
|
|
||||||
|
// For homogeneous vectors (the usual case), the type of the
|
||||||
|
// elements. Will be TYPE_VOID for empty vectors created using
|
||||||
|
// "vector()".
|
||||||
|
TypePtr yield_type;
|
||||||
|
|
||||||
|
// True if this is a vector-of-any, or potentially one (which is
|
||||||
|
// the case for empty vectors created using "vector()").
|
||||||
|
bool any_yield;
|
||||||
|
|
||||||
|
// For heterogeneous vectors, the individual type of each element,
|
||||||
|
// parallel to vector_val. Heterogeneous vectors can arise for
|
||||||
|
// "vector of any" when disparate elements are stored in the vector.
|
||||||
|
//
|
||||||
|
// Thus, if yield_types is non-nil, then we know this is a
|
||||||
|
// vector-of-any.
|
||||||
|
std::vector<TypePtr>* yield_types = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UNDERLYING_ACCESSOR_DEF(ztype, ctype, name) \
|
#define UNDERLYING_ACCESSOR_DEF(ztype, ctype, name) \
|
||||||
|
|
|
@ -1513,7 +1513,8 @@ function order%(v: any, ...%) : index_vec
|
||||||
for ( i = 0; i < n; ++i )
|
for ( i = 0; i < n; ++i )
|
||||||
{
|
{
|
||||||
ind_vv[i] = i;
|
ind_vv[i] = i;
|
||||||
index_map.emplace_back(&vv->At(i));
|
auto tmp_until_later_commit = vv->At(i);
|
||||||
|
index_map.emplace_back(&tmp_until_later_commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( comp )
|
if ( comp )
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue