[Group Hierarchy] Implement new hierarchy lookup queries

Implement a new module called Namespace::Traversal::Denormalized that implements the common descendant lookup queries on top of the recently introduced database model: Namespaces::Descendants.

Methods to implement:

  • self_and_descendant_ids (override)
  • all_project_ids (override)

The methods should be controlled with a feature flag (group_hierarchy_optimization) where the actor is the current namespace record, similar to the Namespace::Traversal::Linear module.

If the feature flag is enabled, we should build a specialized query that does an OR lookup:

  • if cache is not outdated, read the cached date
  • if cache is outdated, fallback to the original implementation

Here you can see an example implementation: !134499 (diffs)

Testing:

Each method needs at least four test cases:

  • When optimization is off for the current group.
  • When the current group has no namespace_descendants record.
  • When the current group has outdated namespace_descendants record.
  • When the current group has up to date namespace_descendants record.
    • To properly test this, you need to create the namespace_descendant rows in a way that the group and project id arrays are correctly filled.
Edited by Adam Hegyi