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};
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
delete vector_val;
|
||||
delete yield_types;
|
||||
}
|
||||
|
||||
ValPtr VectorVal::SizeVal() const
|
||||
|
@ -3192,16 +3197,64 @@ ValPtr VectorVal::SizeVal() const
|
|||
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)
|
||||
{
|
||||
if ( element &&
|
||||
! same_type(element->GetType(), GetType()->AsVectorType()->Yield(), false) )
|
||||
if ( ! CheckElementType(element) )
|
||||
return false;
|
||||
|
||||
if ( index >= vector_val->size() )
|
||||
{
|
||||
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();
|
||||
return true;
|
||||
|
@ -3221,20 +3274,33 @@ bool VectorVal::AssignRepeat(unsigned int index, unsigned int how_many,
|
|||
|
||||
bool VectorVal::Insert(unsigned int index, ValPtr element)
|
||||
{
|
||||
if ( element &&
|
||||
! same_type(element->GetType(), GetType()->AsVectorType()->Yield(), false) )
|
||||
{
|
||||
if ( ! CheckElementType(element) )
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<ValPtr>::iterator it;
|
||||
vector<ZVal>::iterator it;
|
||||
vector<TypePtr>::iterator types_it;
|
||||
|
||||
if ( index < vector_val->size() )
|
||||
{
|
||||
it = std::next(vector_val->begin(), index);
|
||||
if ( yield_types )
|
||||
types_it = std::next(yield_types->begin(), index);
|
||||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
return true;
|
||||
|
@ -3248,6 +3314,12 @@ bool VectorVal::Remove(unsigned int index)
|
|||
auto it = std::next(vector_val->begin(), index);
|
||||
vector_val->erase(it);
|
||||
|
||||
if ( yield_types )
|
||||
{
|
||||
auto types_it = std::next(yield_types->begin(), index);
|
||||
yield_types->erase(types_it);
|
||||
}
|
||||
|
||||
Modified();
|
||||
return true;
|
||||
}
|
||||
|
@ -3276,17 +3348,19 @@ bool VectorVal::AddTo(Val* val, bool /* is_first_init */) const
|
|||
return true;
|
||||
}
|
||||
|
||||
const ValPtr& VectorVal::At(unsigned int index) const
|
||||
ValPtr VectorVal::At(unsigned int index) const
|
||||
{
|
||||
if ( index >= vector_val->size() )
|
||||
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))
|
||||
{
|
||||
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)
|
||||
|
@ -3294,6 +3368,13 @@ unsigned int VectorVal::Resize(unsigned int new_num_elements)
|
|||
unsigned int oldsize = vector_val->size();
|
||||
vector_val->reserve(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;
|
||||
}
|
||||
|
||||
|
@ -3309,6 +3390,9 @@ unsigned int VectorVal::ResizeAtLeast(unsigned int new_num_elements)
|
|||
void VectorVal::Reserve(unsigned int num_elements)
|
||||
{
|
||||
vector_val->reserve(num_elements);
|
||||
|
||||
if ( yield_types )
|
||||
yield_types->reserve(num_elements);
|
||||
}
|
||||
|
||||
ValPtr VectorVal::DoClone(CloneState* state)
|
||||
|
@ -3317,9 +3401,11 @@ ValPtr VectorVal::DoClone(CloneState* state)
|
|||
vv->Reserve(vector_val->size());
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -3332,18 +3418,21 @@ void VectorVal::ValDescribe(ODesc* d) const
|
|||
|
||||
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) )
|
||||
vector_val->at(i)->Describe(d);
|
||||
auto v = At(i);
|
||||
if ( v )
|
||||
v->Describe(d);
|
||||
d->Add(", ");
|
||||
}
|
||||
}
|
||||
|
||||
if ( vector_size != 0 && vector_val->back() )
|
||||
vector_val->back()->Describe(d);
|
||||
auto v = At(last_ind);
|
||||
if ( v )
|
||||
v->Describe(d);
|
||||
}
|
||||
|
||||
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
|
||||
* 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
|
||||
|
@ -1364,7 +1364,29 @@ protected:
|
|||
ValPtr DoClone(CloneState* state) override;
|
||||
|
||||
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) \
|
||||
|
|
|
@ -1513,7 +1513,8 @@ function order%(v: any, ...%) : index_vec
|
|||
for ( i = 0; i < n; ++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 )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue