Skip to content

Commit

Permalink
Speed up ali tree (#4654)
Browse files Browse the repository at this point in the history
* Speed up ali tree

* Fix Tests
  • Loading branch information
haneslinger committed May 6, 2024
1 parent 66148eb commit 1e13fae
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 72 deletions.
29 changes: 28 additions & 1 deletion seed/lib/superperms/orgs/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,34 @@ def get_access_tree(self, from_ali=None) -> list:
if from_ali is None:
from_ali = self.root

return AccessLevelInstance.dump_bulk(from_ali)
alis_ordered_by_lft = list(
AccessLevelInstance.objects.filter(organization=from_ali.organization, lft__gte=from_ali.lft, rgt__lte=from_ali.rgt)
.order_by("-lft")
.values("id", "name", "organization", "path", "lft", "rgt")
)

def populate_children(curr):
curr["children"] = []
lft, rgt = curr["lft"], curr["rgt"]
del curr["lft"]
del curr["rgt"]

while len(alis_ordered_by_lft) > 0:
nxt = alis_ordered_by_lft[-1]
if lft < nxt["lft"] and rgt > nxt["rgt"]: # is descendant
child = alis_ordered_by_lft.pop()
curr["children"].append(child)
populate_children(nxt)
else:
break

if curr["children"] == []:
del curr["children"]

root = alis_ordered_by_lft.pop()
populate_children(root)

return [root]

def __str__(self):
return f"Organization: {self.name}({self.pk})"
Expand Down
40 changes: 15 additions & 25 deletions seed/lib/superperms/tests/test_organization_access_levels.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,9 @@ def test_tree_on_create(self):
assert fake_org.get_access_tree() == [
{
"id": root.pk,
"data": {
"name": "root",
"organization": fake_org.id,
"path": {"Organization A": "root"},
},
"name": "root",
"organization": fake_org.id,
"path": {"Organization A": "root"},
}
]

Expand All @@ -61,35 +59,27 @@ def test_build_out_tree(self):
assert fake_org.get_access_tree() == [
{
"id": fake_org.root.pk,
"data": {
"name": "root",
"organization": fake_org.id,
"path": {"Organization A": "root"},
},
"name": "root",
"organization": fake_org.id,
"path": {"Organization A": "root"},
"children": [
{
"id": aunt.pk,
"data": {
"name": "aunt",
"organization": fake_org.id,
"path": {"Organization A": "root", "2nd gen": "aunt"},
},
"name": "aunt",
"organization": fake_org.id,
"path": {"Organization A": "root", "2nd gen": "aunt"},
},
{
"id": mom.pk,
"data": {
"name": "mom",
"organization": fake_org.id,
"path": {"Organization A": "root", "2nd gen": "mom"},
},
"name": "mom",
"organization": fake_org.id,
"path": {"Organization A": "root", "2nd gen": "mom"},
"children": [
{
"id": me.pk,
"data": {
"name": "me",
"organization": fake_org.id,
"path": {"Organization A": "root", "2nd gen": "mom", "3rd gen": "me"},
},
"name": "me",
"organization": fake_org.id,
"path": {"Organization A": "root", "2nd gen": "mom", "3rd gen": "me"},
}
],
},
Expand Down
2 changes: 1 addition & 1 deletion seed/static/seed/js/controllers/members_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ angular.module('BE.seed.controller.members', []).controller('members_controller'
if (tree === undefined) return;
if (access_level_instances_by_depth[depth] === undefined) access_level_instances_by_depth[depth] = [];
for (const ali of tree) {
access_level_instances_by_depth[depth].push({ id: ali.id, name: ali.data.name });
access_level_instances_by_depth[depth].push({ id: ali.id, name: ali.name });
calculate_access_level_instances_by_depth(ali.children, depth + 1);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ angular.module('BE.seed.controller.organization_add_access_level_modal', [])
if (!tree) return;
if (!access_level_instances_by_depth[depth]) access_level_instances_by_depth[depth] = [];
tree.forEach((ali) => {
access_level_instances_by_depth[depth].push({ id: ali.id, name: ali.data.name });
access_level_instances_by_depth[depth].push({ id: ali.id, name: ali.name });
calculate_access_level_instances_by_depth(ali.children, depth + 1);
});
};
Expand Down
2 changes: 1 addition & 1 deletion seed/static/seed/js/services/ah_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ angular.module('BE.seed.service.ah', []).factory('ah_service', [
if (!tree) return;
if (!access_level_instances_by_depth[depth]) access_level_instances_by_depth[depth] = [];
for (const ali of tree) {
access_level_instances_by_depth[depth].push({ id: ali.id, name: ali.data.name });
access_level_instances_by_depth[depth].push({ id: ali.id, name: ali.name });
recurse_access_levels(ali.children, access_level_instances_by_depth, depth + 1);
}
};
Expand Down
16 changes: 8 additions & 8 deletions seed/static/seed/partials/organization_access_level_tree.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@ <h3 class="tree-header" translate>Access Level Instance Tree</h3>
<div class="level1">{$:: 'Level' | translate $} 1: {$ access_level_names[0] $}</div>
<div class="level0" style="width: 98%; float: right; margin-right: 10px">
<p ng-if="auth.requires_owner" translate>ACCESS_LEVEL_ROOT_TEXT</p>
{$:: access_level_tree[0].data.name $}
{$:: access_level_tree[0].name $}
<button
class="btn btn-info"
ng-if="auth.requires_owner"
type="button"
ng-click="open_edit_al_instance_modal(access_level_tree[0].id, access_level_tree[0].data.name);
ng-click="open_edit_al_instance_modal(access_level_tree[0].id, access_level_tree[0].name);
$event.preventDefault(); $event.stopPropagation();"
tooltip-placement="right"
uib-tooltip="Edit {$ access_level_tree[0].data.name $}"
uib-tooltip="Edit {$ access_level_tree[0].name $}"
>
<i class="fa-solid fa-pencil fa-fw"></i>
</button>
Expand Down Expand Up @@ -119,15 +119,15 @@ <h3 class="tree-header" translate>Access Level Instance Tree</h3>
>
<td class="level-child">
<i ng-if="child.children.length" class="fa-solid fa-chevron-right" id="indicator-{$ child.id $}"></i>
<span>{$ child.data.name $}</span>
<span>{$ child.name $}</span>
</td>
<td>
<button class="btn btn-info" type="button" ng-if="auth.requires_owner" ng-click="open_edit_al_instance_modal(child.id, child.data.name);
$event.preventDefault(); $event.stopPropagation();" tooltip-placement="bottom" uib-tooltip="Edit {$ child.data.name $}">
<button class="btn btn-info" type="button" ng-if="auth.requires_owner" ng-click="open_edit_al_instance_modal(child.id, child.name);
$event.preventDefault(); $event.stopPropagation();" tooltip-placement="bottom" uib-tooltip="Edit {$ child.name $}">
<i class="fa-solid fa-pencil fa-fw"></i>
</button>
<button class="btn btn-info" type="button" ng-if="auth.requires_owner" ng-click="open_delete_al_instance_modal(child.id, child.data.name);
$event.preventDefault(); $event.stopPropagation();" tooltip-placement="bottom" uib-tooltip="Delete {$ child.data.name $}">
<button class="btn btn-info" type="button" ng-if="auth.requires_owner" ng-click="open_delete_al_instance_modal(child.id, child.name);
$event.preventDefault(); $event.stopPropagation();" tooltip-placement="bottom" uib-tooltip="Delete {$ child.name $}">
<i class="fa-solid fa-trash fa-fw"></i>
</button>
</td>
Expand Down
48 changes: 18 additions & 30 deletions seed/tests/test_organization_access_levels.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,22 @@ def test_access_level_tree(self):
sibling = self.org.add_new_access_level_instance(self.org.root.id, "sibling")
child_dict = {
"id": self.child_level_instance.pk,
"data": {
"name": "child",
"organization": self.org.id,
"path": {"root": "root", "child": "child"},
},
"name": "child",
"organization": self.org.id,
"path": {"root": "root", "child": "child"},
}
sibling_dict = {
"id": sibling.pk,
"data": {
"name": "sibling",
"organization": self.org.id,
"path": {"root": "root", "child": "sibling"},
},
"name": "sibling",
"organization": self.org.id,
"path": {"root": "root", "child": "sibling"},
}

root_dict = {
"id": self.org.root.pk,
"data": {
"name": self.root_level_instance.name,
"organization": self.org.id,
"path": {"root": "root"},
},
"name": self.root_level_instance.name,
"organization": self.org.id,
"path": {"root": "root"},
}

# get tree
Expand Down Expand Up @@ -157,27 +151,21 @@ def test_add_new_access_level_instance(self):
"access_level_tree": [
{
"id": self.org.root.pk,
"data": {
"name": self.root_level_instance.name,
"organization": self.org.id,
"path": {"root": "root"},
},
"name": self.root_level_instance.name,
"organization": self.org.id,
"path": {"root": "root"},
"children": [
{
"id": aunt.pk,
"data": {
"name": "aunt",
"organization": self.org.id,
"path": {"root": "root", "child": "aunt"},
},
"name": "aunt",
"organization": self.org.id,
"path": {"root": "root", "child": "aunt"},
},
{
"id": self.child_level_instance.pk,
"data": {
"name": "child",
"organization": self.org.id,
"path": {"root": "root", "child": "child"},
},
"name": "child",
"organization": self.org.id,
"path": {"root": "root", "child": "child"},
},
],
}
Expand Down
8 changes: 3 additions & 5 deletions seed/views/v3/access_levels.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,9 @@ def tree(self, request, organization_pk=None):
curr.append(
{
"id": a.pk,
"data": {
"name": a.name,
"organization": org.id,
"path": a.path,
},
"name": a.name,
"organization": org.id,
"path": a.path,
"children": [],
}
)
Expand Down

0 comments on commit 1e13fae

Please sign in to comment.