performance - 快速遍历ACL的策略

标签 performance algorithm tree acl

我们目前正在开发一个项目,其中主要域对象是内容节点,并且我们正在使用类似 ACL 的系统,其中层次结构中的每个节点都可以包含覆盖或补充其父节点的规则。例如,一切都基于角色和行动。

Node 1 - {Deny All, Allow Role1 View}
\- Node 2 - {Allow Role2 View}
   \- Node 3 - {Deny Role1 View}

在这种情况下,规则将按照从上到下的顺序读取,因此节点 3 只能由角色 2 看到。它的概念并不复杂。

检索单个节点的规则可能会导致一些查询,获取所有父节点,然后重新创建规则列表并评估它们,但这个过程可能很麻烦,因为层次结构可能会变得非常深并且可能有很多每个节点上的规则。

我一直在考虑为每个节点准备一个包含预先计算规则的表,每当权限更改时都可以重新创建该表并将其传播到更新后的所有叶节点。

您认为还有其他策略来加速规则的检索和计算吗?理想情况下,它应该在单个查询中完成,但树并不是最好的结构。

最佳答案

我认为 Observer Pattern可能会进行调整。

这个想法是每个Node维护一个预先计算的列表,并且只需由其父节点通知任何更新,以便它可以重新计算该列表。

这可以通过两种不同的方式完成:

  1. 通知发生了更改,但不重新计算任何内容
  2. 每次更新时重新计算

如果可能的话,我建议使用1,因为它不涉及在更新根时重新计算整个世界,并且仅在需要时重新计算(事实上是惰性评估),但您可能更喜欢第二个如果您很少更新但需要极快的检索(但存在更多并发问题),则可以选择此选项。

让我们举例说明解决方案 1:

Root ___ Node1 ___ Node1A
     \         \__ Node1B
      \_ Node2 ___ Node2A
               \__ Node2B

现在,首先,如果我要求 Node2A 规则,它们都没有预先计算任何东西(它们都处于脏状态):

  • Node2A 意识到它是脏的:它查询 Node2 规则
  • Node2 意识到它是脏的:它查询 Root
  • Root 没有任何父级,因此它不能是脏的,它将其规则发送到 Node2
  • Node2 缓存来自 Root 的答案,将其规则与从 Root 接收到的规则合并并清除脏位,它发送以下结果合并(现已缓存)到 Node2A
  • Node2A缓存、合并、清理脏位并返回结果

如果我随后请求 Node2B 规则:

  • Node2B 是脏的,它查询 Node2
  • Node2 是干净的,它会回复
  • Node2B缓存、合并、清理脏位并返回结果

请注意,Node2 没有重新计算任何内容。

在更新情况下:

  • 我更新 Node1:我使用 Root 缓存规则重新计算新规则并向 Node1ANode1B 发送节拍 通知他们缓存已过时
  • Node1ANode1B 设置了它们的脏位,如果它们有 child ,它们也会传播此通知

请注意,因为我缓存了 Root 规则,所以我不必查询 Root 对象,如果这是一个足够简单的操作,您可能不希望将它们缓存在all:如果您不在这里玩分布式游戏,并且查询 Root 仅涉及内存往返,您可能不希望重复它,以节省一些内存和簿记。

希望它能让你继续前进。

关于performance - 快速遍历ACL的策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2636955/

相关文章:

c - 第一个子级 - 下一个兄弟树中某个级别的节点数

python - 如何从邻接列表构建嵌套树结构?

performance - 在 Haskell 中优化 n-queens

显示大文件的 JavaFX textarea

performance - Haskell 计算素数时的效率

java - 在 Java 中针对 Map 执行最佳 levenshtein 匹配的最佳方法

string - 名称匹配的字符串相似性

c++ - 用字典解析字符串的算法

java - 递归方法在每一步返回一个字符串?

performance - Actionscript 3 绘制大矩形导致 FPS 大幅下降