mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00
restore support for vectors with holes
remove vestigial comment
This commit is contained in:
parent
ff393dbd8a
commit
c1903afb3b
2 changed files with 94 additions and 57 deletions
132
src/Val.cc
132
src/Val.cc
|
@ -3241,7 +3241,7 @@ ValPtr TypeVal::DoClone(CloneState* state)
|
||||||
|
|
||||||
VectorVal::VectorVal(VectorTypePtr t) : Val(t)
|
VectorVal::VectorVal(VectorTypePtr t) : Val(t)
|
||||||
{
|
{
|
||||||
vector_val = new vector<ZVal>();
|
vector_val = new vector<std::optional<ZVal>>();
|
||||||
yield_type = t->Yield();
|
yield_type = t->Yield();
|
||||||
|
|
||||||
auto y_tag = yield_type->Tag();
|
auto y_tag = yield_type->Tag();
|
||||||
|
@ -3255,14 +3255,19 @@ VectorVal::~VectorVal()
|
||||||
{
|
{
|
||||||
int n = yield_types->size();
|
int n = yield_types->size();
|
||||||
for ( auto i = 0; i < n; ++i )
|
for ( auto i = 0; i < n; ++i )
|
||||||
ZVal::DeleteIfManaged((*vector_val)[i], (*yield_types)[i]);
|
{
|
||||||
|
auto& elem = (*vector_val)[i];
|
||||||
|
if ( elem )
|
||||||
|
ZVal::DeleteIfManaged(*elem, (*yield_types)[i]);
|
||||||
|
}
|
||||||
delete yield_types;
|
delete yield_types;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( managed_yield )
|
else if ( managed_yield )
|
||||||
{
|
{
|
||||||
for ( auto& elem : *vector_val )
|
for ( auto& elem : *vector_val )
|
||||||
ZVal::DeleteManagedType(elem);
|
if ( elem )
|
||||||
|
ZVal::DeleteManagedType(*elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete vector_val;
|
delete vector_val;
|
||||||
|
@ -3320,7 +3325,9 @@ bool VectorVal::Assign(unsigned int index, ValPtr element)
|
||||||
|
|
||||||
if ( index >= n )
|
if ( index >= n )
|
||||||
{
|
{
|
||||||
AddHoles(index - n);
|
if ( index > n )
|
||||||
|
AddHoles(index - n);
|
||||||
|
|
||||||
vector_val->resize(index + 1);
|
vector_val->resize(index + 1);
|
||||||
if ( yield_types )
|
if ( yield_types )
|
||||||
yield_types->resize(index + 1);
|
yield_types->resize(index + 1);
|
||||||
|
@ -3330,14 +3337,21 @@ bool VectorVal::Assign(unsigned int index, ValPtr element)
|
||||||
{
|
{
|
||||||
const auto& t = element->GetType();
|
const auto& t = element->GetType();
|
||||||
(*yield_types)[index] = t;
|
(*yield_types)[index] = t;
|
||||||
ZVal::DeleteIfManaged((*vector_val)[index], t);
|
auto& elem = (*vector_val)[index];
|
||||||
(*vector_val)[index] = ZVal(std::move(element), t);
|
if ( elem )
|
||||||
|
ZVal::DeleteIfManaged(*elem, t);
|
||||||
|
elem = ZVal(std::move(element), t);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( managed_yield )
|
auto& elem = (*vector_val)[index];
|
||||||
ZVal::DeleteManagedType((*vector_val)[index]);
|
if ( managed_yield && elem )
|
||||||
(*vector_val)[index] = ZVal(std::move(element), yield_type);
|
ZVal::DeleteManagedType(*elem);
|
||||||
|
|
||||||
|
if ( element )
|
||||||
|
elem = ZVal(std::move(element), yield_type);
|
||||||
|
else
|
||||||
|
elem = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
Modified();
|
Modified();
|
||||||
|
@ -3361,7 +3375,7 @@ bool VectorVal::Insert(unsigned int index, ValPtr element)
|
||||||
if ( ! CheckElementType(element) )
|
if ( ! CheckElementType(element) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
vector<ZVal>::iterator it;
|
vector<std::optional<ZVal>>::iterator it;
|
||||||
vector<TypePtr>::iterator types_it;
|
vector<TypePtr>::iterator types_it;
|
||||||
|
|
||||||
auto n = vector_val->size();
|
auto n = vector_val->size();
|
||||||
|
@ -3371,28 +3385,36 @@ bool VectorVal::Insert(unsigned int index, ValPtr element)
|
||||||
it = std::next(vector_val->begin(), index);
|
it = std::next(vector_val->begin(), index);
|
||||||
if ( yield_types )
|
if ( yield_types )
|
||||||
{
|
{
|
||||||
ZVal::DeleteIfManaged(*it, element->GetType());
|
if ( *it )
|
||||||
|
ZVal::DeleteIfManaged(**it, element->GetType());
|
||||||
types_it = std::next(yield_types->begin(), index);
|
types_it = std::next(yield_types->begin(), index);
|
||||||
}
|
}
|
||||||
else if ( managed_yield )
|
else if ( managed_yield )
|
||||||
ZVal::DeleteManagedType(*it);
|
ZVal::DeleteManagedType(**it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
it = vector_val->end();
|
it = vector_val->end();
|
||||||
if ( yield_types )
|
if ( yield_types )
|
||||||
types_it = yield_types->end();
|
types_it = yield_types->end();
|
||||||
AddHoles(index - n);
|
|
||||||
|
if ( index > n )
|
||||||
|
AddHoles(index - n);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( yield_types )
|
if ( element )
|
||||||
{
|
{
|
||||||
const auto& t = element->GetType();
|
if ( yield_types )
|
||||||
yield_types->insert(types_it, t);
|
{
|
||||||
vector_val->insert(it, ZVal(std::move(element), t));
|
const auto& t = element->GetType();
|
||||||
|
yield_types->insert(types_it, t);
|
||||||
|
vector_val->insert(it, ZVal(std::move(element), t));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vector_val->insert(it, ZVal(std::move(element), yield_type));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vector_val->insert(it, ZVal(std::move(element), yield_type));
|
vector_val->insert(it, std::nullopt);
|
||||||
|
|
||||||
Modified();
|
Modified();
|
||||||
return true;
|
return true;
|
||||||
|
@ -3405,7 +3427,7 @@ void VectorVal::AddHoles(int nholes)
|
||||||
fill_t = base_type(TYPE_ANY);
|
fill_t = base_type(TYPE_ANY);
|
||||||
|
|
||||||
for ( auto i = 0; i < nholes; ++i )
|
for ( auto i = 0; i < nholes; ++i )
|
||||||
vector_val->emplace_back(ZVal(fill_t));
|
vector_val->emplace_back(std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VectorVal::Remove(unsigned int index)
|
bool VectorVal::Remove(unsigned int index)
|
||||||
|
@ -3418,12 +3440,13 @@ bool VectorVal::Remove(unsigned int index)
|
||||||
if ( yield_types )
|
if ( yield_types )
|
||||||
{
|
{
|
||||||
auto types_it = std::next(yield_types->begin(), index);
|
auto types_it = std::next(yield_types->begin(), index);
|
||||||
ZVal::DeleteIfManaged(*it, *types_it);
|
if ( *it )
|
||||||
|
ZVal::DeleteIfManaged(**it, *types_it);
|
||||||
yield_types->erase(types_it);
|
yield_types->erase(types_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( managed_yield )
|
else if ( managed_yield )
|
||||||
ZVal::DeleteManagedType(*it);
|
ZVal::DeleteManagedType(**it);
|
||||||
|
|
||||||
vector_val->erase(it);
|
vector_val->erase(it);
|
||||||
|
|
||||||
|
@ -3460,33 +3483,33 @@ ValPtr VectorVal::At(unsigned int index) const
|
||||||
if ( index >= vector_val->size() )
|
if ( index >= vector_val->size() )
|
||||||
return Val::nil;
|
return Val::nil;
|
||||||
|
|
||||||
|
auto& elem = (*vector_val)[index];
|
||||||
|
if ( ! elem )
|
||||||
|
return Val::nil;
|
||||||
|
|
||||||
const auto& t = yield_types ? (*yield_types)[index] : yield_type;
|
const auto& t = yield_types ? (*yield_types)[index] : yield_type;
|
||||||
|
|
||||||
return (*vector_val)[index].ToVal(t);
|
return elem->ToVal(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Func* sort_function_comp = nullptr;
|
static Func* sort_function_comp = nullptr;
|
||||||
|
|
||||||
// Used for indirect sorting to support order().
|
// Used for indirect sorting to support order().
|
||||||
static std::vector<const ZVal*> index_map;
|
static std::vector<const std::optional<ZVal>*> index_map;
|
||||||
|
|
||||||
// The yield type of the vector being sorted.
|
// The yield type of the vector being sorted.
|
||||||
static TypePtr sort_type;
|
static TypePtr sort_type;
|
||||||
static bool sort_type_is_managed = false;
|
|
||||||
|
|
||||||
static bool sort_function(const ZVal& a, const ZVal& b)
|
static bool sort_function(const std::optional<ZVal>& a, const std::optional<ZVal>& b)
|
||||||
{
|
{
|
||||||
// Missing values are only applicable for managed types.
|
if ( ! a )
|
||||||
if ( sort_type_is_managed )
|
return false;
|
||||||
{
|
|
||||||
if ( ! a.ManagedVal() )
|
|
||||||
return 0;
|
|
||||||
if ( ! b.ManagedVal() )
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto a_v = a.ToVal(sort_type);
|
if ( ! b )
|
||||||
auto b_v = b.ToVal(sort_type);
|
return true;
|
||||||
|
|
||||||
|
auto a_v = a->ToVal(sort_type);
|
||||||
|
auto b_v = b->ToVal(sort_type);
|
||||||
|
|
||||||
auto result = sort_function_comp->Invoke(a_v, b_v);
|
auto result = sort_function_comp->Invoke(a_v, b_v);
|
||||||
int int_result = result->CoerceToInt();
|
int int_result = result->CoerceToInt();
|
||||||
|
@ -3494,19 +3517,37 @@ static bool sort_function(const ZVal& a, const ZVal& b)
|
||||||
return int_result < 0;
|
return int_result < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool signed_sort_function (const ZVal& a, const ZVal& b)
|
static bool signed_sort_function(const std::optional<ZVal>& a, const std::optional<ZVal>& b)
|
||||||
{
|
{
|
||||||
return a.AsInt() < b.AsInt();
|
if ( ! a )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( ! b )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return a->AsInt() < b->AsInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool unsigned_sort_function (const ZVal& a, const ZVal& b)
|
static bool unsigned_sort_function(const std::optional<ZVal>& a, const std::optional<ZVal>& b)
|
||||||
{
|
{
|
||||||
return a.AsCount() < b.AsCount();
|
if ( ! a )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( ! b )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return a->AsCount() < b->AsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool double_sort_function (const ZVal& a, const ZVal& b)
|
static bool double_sort_function(const std::optional<ZVal>& a, const std::optional<ZVal>& b)
|
||||||
{
|
{
|
||||||
return a.AsDouble() < b.AsDouble();
|
if ( ! a )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( ! b )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return a->AsDouble() < b->AsDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool indirect_sort_function(size_t a, size_t b)
|
static bool indirect_sort_function(size_t a, size_t b)
|
||||||
|
@ -3535,9 +3576,8 @@ void VectorVal::Sort(Func* cmp_func)
|
||||||
reporter->RuntimeError(GetLocationInfo(), "cannot sort a vector-of-any");
|
reporter->RuntimeError(GetLocationInfo(), "cannot sort a vector-of-any");
|
||||||
|
|
||||||
sort_type = yield_type;
|
sort_type = yield_type;
|
||||||
sort_type_is_managed = ZVal::IsManagedType(sort_type);
|
|
||||||
|
|
||||||
bool (*sort_func)(const ZVal&, const ZVal&);
|
bool (*sort_func)(const std::optional<ZVal>&, const std::optional<ZVal>&);
|
||||||
|
|
||||||
if ( cmp_func )
|
if ( cmp_func )
|
||||||
{
|
{
|
||||||
|
@ -3572,7 +3612,6 @@ VectorValPtr VectorVal::Order(Func* cmp_func)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort_type = yield_type;
|
sort_type = yield_type;
|
||||||
sort_type_is_managed = ZVal::IsManagedType(sort_type);
|
|
||||||
|
|
||||||
bool (*sort_func)(size_t, size_t);
|
bool (*sort_func)(size_t, size_t);
|
||||||
|
|
||||||
|
@ -3666,8 +3705,9 @@ ValPtr VectorVal::DoClone(CloneState* state)
|
||||||
|
|
||||||
for ( auto i = 0; i < n; ++i )
|
for ( auto i = 0; i < n; ++i )
|
||||||
{
|
{
|
||||||
auto vc = At(i)->Clone(state);
|
auto elem = At(i);
|
||||||
vv->Append(std::move(vc));
|
if ( elem )
|
||||||
|
vv->Assign(i, elem->Clone(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
return vv;
|
return vv;
|
||||||
|
|
19
src/Val.h
19
src/Val.h
|
@ -1505,10 +1505,6 @@ public:
|
||||||
*/
|
*/
|
||||||
bool Assign(unsigned int index, ValPtr element);
|
bool Assign(unsigned int index, ValPtr element);
|
||||||
|
|
||||||
// Note: the following nullptr method can also go upon removing the above.
|
|
||||||
void Assign(unsigned int index, std::nullptr_t)
|
|
||||||
{ Assign(index, ValPtr{}); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assigns a given value to multiple indices in the vector.
|
* Assigns a given value to multiple indices in the vector.
|
||||||
* @param index The starting index to assign to.
|
* @param index The starting index to assign to.
|
||||||
|
@ -1581,18 +1577,19 @@ public:
|
||||||
/**
|
/**
|
||||||
* Returns the given element in a given underlying representation.
|
* Returns the given element in a given underlying representation.
|
||||||
* Enables efficient vector access. Caller must ensure that the
|
* Enables efficient vector access. Caller must ensure that the
|
||||||
* index lies within the vector's range.
|
* index lies within the vector's range, and does not point to
|
||||||
|
* a "hole".
|
||||||
* @param index The position in the vector of the element to return.
|
* @param index The position in the vector of the element to return.
|
||||||
* @return The element's underlying value.
|
* @return The element's underlying value.
|
||||||
*/
|
*/
|
||||||
bro_uint_t CountAt(unsigned int index) const
|
bro_uint_t CountAt(unsigned int index) const
|
||||||
{ return (*vector_val)[index].uint_val; }
|
{ return (*vector_val)[index]->uint_val; }
|
||||||
const RecordVal* RecordValAt(unsigned int index) const
|
const RecordVal* RecordValAt(unsigned int index) const
|
||||||
{ return (*vector_val)[index].record_val; }
|
{ return (*vector_val)[index]->record_val; }
|
||||||
bool BoolAt(unsigned int index) const
|
bool BoolAt(unsigned int index) const
|
||||||
{ return static_cast<bool>((*vector_val)[index].uint_val); }
|
{ return static_cast<bool>((*vector_val)[index]->uint_val); }
|
||||||
const StringVal* StringValAt(unsigned int index) const
|
const StringVal* StringValAt(unsigned int index) const
|
||||||
{ return (*vector_val)[index].string_val; }
|
{ return (*vector_val)[index]->string_val; }
|
||||||
const String* StringAt(unsigned int index) const
|
const String* StringAt(unsigned int index) const
|
||||||
{ return StringValAt(index)->AsString(); }
|
{ return StringValAt(index)->AsString(); }
|
||||||
|
|
||||||
|
@ -1601,7 +1598,7 @@ protected:
|
||||||
* Returns the element at a given index or nullptr if it does not exist.
|
* Returns the element at a given index or nullptr if it does not exist.
|
||||||
* @param index The position in the vector of the element to return.
|
* @param index The position in the vector of the element to return.
|
||||||
* @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.
|
||||||
*
|
*
|
||||||
* Protected to ensure callers pick one of the differentiated accessors
|
* Protected to ensure callers pick one of the differentiated accessors
|
||||||
* above, as appropriate, with ValAt() providing the original semantics.
|
* above, as appropriate, with ValAt() providing the original semantics.
|
||||||
|
@ -1624,7 +1621,7 @@ private:
|
||||||
// Add the given number of "holes" to the end of a vector.
|
// Add the given number of "holes" to the end of a vector.
|
||||||
void AddHoles(int nholes);
|
void AddHoles(int nholes);
|
||||||
|
|
||||||
std::vector<ZVal>* vector_val;
|
std::vector<std::optional<ZVal>>* vector_val;
|
||||||
|
|
||||||
// For homogeneous vectors (the usual case), the type of the
|
// For homogeneous vectors (the usual case), the type of the
|
||||||
// elements. Will be TYPE_VOID for empty vectors created using
|
// elements. Will be TYPE_VOID for empty vectors created using
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue