禁用嵌套组件分支的最有效方法,最好是 O(1) 操作
我正在研究一些涉及执行许多细粒度命令并以同步确定性方式处理其副作用的事情。我有一个可能很大的对象有向循环图,每个对象都包含一个委托。这些对象被分组为组件。组件是分层的,可以嵌套到任意深度。对象之间的连接可以跨越组件边界。
有两个列表(执行缓冲区、暂存缓冲区),其中一些对象将添加到其中。当执行缓冲区中的对象被迭代时,它们的委托被执行,其结果决定哪些(如果有)连接的对象将被放置在暂存缓冲区中。当迭代完成时,缓冲区被交换,前一个执行缓冲区被清除,并且循环重新开始。
除了确定将哪些连接对象添加到暂存缓冲区之外,某些委托还会导致禁用组件。禁用后,不应处理该分支内的任何对象。
我需要最有效的方法来指定/识别禁用哪些组件,以防止处理对象。以下是我所知道的选项...
仅在分支的父组件上设置禁用标志。当考虑要执行的每个对象时,一直爬到根组件以查看是否有任何标记为禁用...最多 O(n),其中 n 是对象所属组件的深度。这可以通过维护字典来优化,以便每个循环都需要执行一次任何给定组件的爬升。
在分支中的所有组件上设置禁用标志...每个对象的O(1),因为它只需要检查其所有者是否设置了禁用标志。但是将分支标记为禁用的时间复杂度为 O(n),其中 n 是分支中组件的数量。
为每个组件分配一对 Farey 分数 来表示 嵌套间隔,并维护禁用间隔的全局记录。当考虑执行每个对象时,检查其所属组件的时间间隔是否落在禁用的时间间隔之一内。每个对象最多为 O(n),其中 n 是禁用的组件数量。这也可以通过维护字典来优化,以便每个周期需要执行一次检查任何给定组件的间隔。我不确定这个的可扩展性。在分数开始用完小数点之前,分支可以嵌套多大/多深?
执行某种指针魔术,以便分支中的所有组件共享禁用标志。
编辑: 可以显式和/或隐式地禁用组件的分支。显式意味着分支已被标记为禁用。隐式意味着分支被视为禁用,因为组件层次结构中的祖先分支被标记为禁用。如果给定分支 C 被显式禁用,并且祖先分支 A 也被禁用,则重新启用 C >A 不应导致启用 C。考虑到这一点,我不明白选项 4 如何与指针或共享引用一起使用。我考虑过有两个标志,一个用于显式设置,一个用于隐式设置。一个组件的显式标志可以用作子组件的隐式标志。但这只能让我禁用直接子组件。
I am working on something that involves execution of many fine-grained commands and handling their side-effects in a synchronous deterministic fashion. I have a potentially large directed cyclic graph of objects, each of which contains a delegate. These objects are grouped into components. Components are hierarchical and can be nested to any depth. The connections between objects can cross component boundaries.
There are two lists (execution buffer, staging buffer) to which some of these objects will be added. As objects in the execution buffer are iterated, their delegates are executed, the result of which determines which (if any) connected objects will be placed in the staging buffer. When iteration is complete, the buffers are swapped, the former execution buffer cleared, and the cycle starts over.
In addition to determining which connected objects to add to the staging buffer, some delegates will result in disabling a component. When disabled, none of the objects within that branch should be processed.
I need the most efficient possible way to specify/identify what components are disabled in order to prevent objects from being processed. The following are options I am aware of...
Set a disabled flag on only the parent component of a branch. When considering each object for execution, climb all the way to the root component to see if any are marked disabled... Up to O(n) where n is the depth of the object's owning component. This can be optimized by maintaining a dictionary, so that climbing for any given component need be performed once each cycle.
Set a disabled flag on all components in a branch... O(1) for each object because it only needs to check if its owner has its disabled flag set. But O(n) to mark a branch as disabled where n is the number of components in branch.
Assign each component a pair of Farey fractions to represent a nested interval, and maintain global record of intervals that are disabled. When considering each object for execution, check if its owning component's interval falls within one of the disabled intervals. Up to O(n) for each object where n is the number of components disabled. This can also be optimized by maintaining a dictionary, so that checking the intervals of any given component need be performed once each cycle. I'm not sure about the scalability of this. How large/deeply nested can a branch become before the fractions start running out of decimal points?
Perform some sort of pointer magic so that all components in a branch share a disabled flag.
Edit:
A branch of components can be disabled explicitly and/or implicitly. Explicit means that a branch has been marked as disabled. Implicit means a branch is considered disabled because an ancestor branch in the component hierarchy is marked as disabled. If a given branch C is explicitly disabled and an ancestor branch A is also disabled, re-enabling A should not result in C being enabled. With that in mind I don't see how option 4 could work with a pointer or shared reference. I thought about having two flags, one for an explicit setting and one for implicit. An explicit flag for one component could be used as the implicit flag for child components. But that only lets me disable the immediate child components.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
选项 4 听起来很有可能。您所需要的只是一个引用类型,我将其称为
FlagHolder
:然后为每个组仅创建一个
FlagHolder
,该组将作为一个单元被禁用,并将其传递给所有个别物体。Option 4 sounds very possible. All you need is a reference type, I'll call it
FlagHolder
:Then create only one
FlagHolder
per group that will be disabled as a unit, and pass it to all the individual objects.