-
Notifications
You must be signed in to change notification settings - Fork 249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Core] Introducing proper insert method to PointerVectorSet #12087
[Core] Introducing proper insert method to PointerVectorSet #12087
Conversation
ping @KratosMultiphysics/altair so that everyone is aware as this is an important change, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sunethwarna! I am not sure about the set function implementation and I think the insert implementation is not coherent. Also, I like more the implementation of the range inserts than the value insert itself. I think the range ones are more clear and have less ifs
|
||
*i = pData; | ||
return i; | ||
} else if (EqualKeyTo(KeyOf(*position_hint))(*ptr_begin())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think here should be else if (position_hint == cbegin())
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can change it :). As far as i see, current implementation is the same, except, it checks the value of the begin rather than the iterator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But the value check should come in the main if like other statements of upper if elses
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense and done :)
*/ | ||
template <class InputIterator> | ||
void insert(InputIterator First, InputIterator Last) | ||
void insert(InputIterator first, InputIterator last) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we have an additional argument (or a separate method) for insert_sorted_values
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is little bit dangerous. Thats why I put insert(const PointVectorSet& rOther)
overload to avoid doing sorting and making it unique. insert(end(), value)
is having O(N)
cost if we are inserting a sorted array which can be used to construct a quick sorted PointerVectorSet
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we have an additional argument (or a separate method) for insert_sorted_values?
definitely not. The whole point of refactoring PointerVectorSet
is to enforce its contract (sortedness and uniqueness) regardless of user input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with @sunethwarna that adding ordered set of entities is far faster than insert without assuming that. However creating the first PointerVectorSet would involve the sort.
Disagree with @matekelemen in the priority of robustness over performance for this case that the complexity of the algorithm changes from N to NlogN. Please note that in most of the mesh generation modelers we are adding millions of entities (to sub-modelparts) which we create with ordered indices (starting from the largest) and the first sort of those is an unnecessary operation
Nevertheless, I agree that this can be added afterward
kratos/containers/set_function.h
Outdated
* @param data The input object of type TDataType. | ||
* @return A non-const reference pointer or reference to the same object as provided in the parameter. | ||
*/ | ||
std::conditional_t<HasOperatorsDefined, TDataType&, TDataType*> operator()(TDataType& rData) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is somehow weird to return different types and the final objective is not clear if one is not familiar with the implementation. I think it would be more clear to have the operator < and == defined here properly depending if the value has those defines or not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then the question is, what is the key_type
of a PointerVectorSet<SomeDataType>
where the SomeDataType
does not have the operator<
and/or operator==
defined?
We need to put somewhere this conditional_t
if we want to illustrate that if they use PointerVectorSet
with TDataType
which does not have the operator<
and operator==
defined.
The above solution was the least intrusive AFAIK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I see, This is the GetKey function which make sense to return the pointer instead of value if the value is not comparable. Then I would add the GetKey(or an equivalent) to the name to be more clear. (I admit that mine wasn't clear neither 😅)
I agree with the behavior then!
…_set/introduce_insert
@pooyan-dadvand I addressed your suggestions/comments. Could you have a look? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Already in a good shape! Some minor comments
{ | ||
// all 4 bounds are equal, hence this can be inserted without checking further | ||
if (lower_bound_first == mData.end()) { | ||
for (auto it = first; it != last; ++it) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't be better to reserve first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done :)
return iterator(mData.end() - 1); | ||
} else { | ||
// given position is invalid. Hence, discarding the hint. | ||
return insert(value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a minor improvement, but I would not calling the insert here and just add the last statement of ifs in insert to avoid reevaluating for push_back
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not possible, I need to add all if statements, because we need to do all the checks if the hint is discarded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see....
return mData.insert(mData.begin(), value); | ||
} else { | ||
// given position is invalid. Hence, discarding the hint. | ||
return insert(value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As explained before.
return mData.insert(mData.begin() + (position_hint - cbegin()), value); | ||
} else { | ||
// given position is invalid. Hence, discarding the hint. | ||
return insert(value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As explained before.
kratos/containers/set_function.h
Outdated
* @author Suneth Warnakulasuriya | ||
*/ | ||
template<class TDataType> | ||
class SetFunction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you please give a more descriptive name to this function? PointerSetGetKey
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done :)... Changed to KeyGenerator
.
@pooyan-dadvand I addressed your comments. Could you take a look :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
return iterator(mData.end() - 1); | ||
} else { | ||
// given position is invalid. Hence, discarding the hint. | ||
return insert(value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see....
📝 Description
This PR is introducing the
PointerVectorSet::insert
method which is suppose to replace the currently usedPointerVectorSet::push_back
method. This is one of many PRs addressing the issue #11363 .❗ This is one of many PRs which will address the points mentioned in #11363.
Followings chages are done:
insert(pointer)
method is changed not to sort anymore, and to put the new element in the correct position while keeping the sortedness in thePointerVectorSet
. This assumesPointerVectorSet
is already in a sorted state.insert(begin, end)
method also changed not to sort the existing data, it sorts the incoming range and make it unique before inserting them to themData
. This also assumesPointerVectorSet
is already in sorted state.insert(position_hint, pointer)
uses the position hint if it is valid, otherwise it discards theposition_hint
and puts the new pointer in the correct place. This also assumesPointerVectorSet
is already in sorted state.TGetKeyType
is changed to return memory locations if the providedTDataType
does not haveoperator<
andoperator==
defined. Otherwise,TGetKeyType
returns the exact input object.🆕 Changelog
insert
methods to assumePointerVectorSet
is always sorted when inserting new elements.SetFunction
to get the memory location ifoperator<
andoperator==
not defined, otherwise it returns the input object..PointerVectorSet
to be based on memory or exact objects by usingSetFunction
insert
methods