What i would like to do is the following.
(Not sure if this question should go to StackOverflow, or here)
Consider a datastructure like this:
interface IAction {
IAction[] afterActions()
IAction[] beforeActions()
void execute()
}
What I would like to do is execute()
a IAction
collection, in the manner, that
- All
beforeActions()
are executed before the supplier of thebeforeActions()
calls result. - All
afterActions()
are executed after the supplier of theafterActions()
calls result. - Be able to detect "cyclic dependencies", so if one should execute before and after another, or after itself, or after another action, that on any path should execute before, etc.
In other worlds I would like to "sort" these actions in an executable order.
I would like to get only an explanation on how I should (could) do this, I don't expect anyone to implement anything for me (notice, that I intentionally didn't specify a language).
If you know about any generic algorithm for this purpose, that you think is suitable for the problem, please feel free to share with a minimal explanation, on how you would translate it to this problem
EDIT
After thinking a lot about the problem, I figured out, that dependency-wise the afterActions()
is absolutely useless (an action shouldn't know about what executes after it, it should only describe what it needs to be completed before, to successfully execute). Knowing this I ended up doing something like what @Rafael Eyng suggested:
I created an Iterator
, which wrapped the original collection, and had a next()
, which always returned the next (resolved) action. The iterator was not stateless, it had a reference to the collection with all the action, and had a (growing) Set
of actions, which are resolved. To achieve this, every time next()
was called i did the following:
- Iterate on all the actions
- If one has no dependencies, or all of them are in the already resolved list, then it can be returned as next.
- If it has dependencies, then recursively do this for all the prerequisites.
- I was also collecting the already visited actions, from the root of the recursive call, so cycles could be detected