Forum OpenACS Development: Response to ACS 4.x won't scale (I hope I am wrong)
Posted by
Dave Hwang
on 10/27/01 12:35 PM
I modified Jon's upgraded acs_permission.permission_p() code and got some significant performance improvements by making two changes. First, I ditched using DECODE and WHERE EXISTS, in favor of simply using COUNT() and using sub-selects instead of joins in the group related sections. Secondly, I changed the order of precedence in the permissions check to Public, direct, group, and group_rels.
create or replace package body acs_permission as procedure grant_permission ( object_id acs_permissions.object_id%TYPE, grantee_id acs_permissions.grantee_id%TYPE, privilege acs_permissions.privilege%TYPE ) as begin insert into acs_permissions (object_id, grantee_id, privilege) values (object_id, grantee_id, privilege); exception when dup_val_on_index then return; end grant_permission; -- procedure revoke_permission ( object_id acs_permissions.object_id%TYPE, grantee_id acs_permissions.grantee_id%TYPE, privilege acs_permissions.privilege%TYPE ) as begin delete from acs_permissions where object_id = revoke_permission.object_id and grantee_id = revoke_permission.grantee_id and privilege = revoke_permission.privilege; end revoke_permission; -- function permission_p ( object_id acs_objects.object_id%TYPE, party_id parties.party_id%TYPE, privilege acs_privileges.privilege%TYPE ) return char as v_count INTEGER; begin -- Check public permissions SELECT COUNT(*) INTO v_count FROM acs_object_grantee_priv_map WHERE object_id = permission_p.object_id AND privilege = permission_p.privilege AND grantee_id = -1; if v_count > 0 then return 't'; end if; -- -- Check direct permissions SELECT COUNT(*) INTO v_count FROM acs_object_grantee_priv_map WHERE object_id = permission_p.object_id AND privilege = permission_p.privilege AND grantee_id = permission_p.party_id; if v_count > 0 then return 't'; end if; -- -- Check group permmissions SELECT COUNT(*) INTO v_count FROM acs_object_grantee_priv_map WHERE object_id = permission_p.object_id AND privilege = permission_p.privilege AND grantee_id IN (SELECT DISTINCT group_id FROM group_approved_member_map WHERE member_id = permission_p.party_id); if v_count > 0 then return 't'; end if; -- -- relational segment approved group SELECT COUNT(*) INTO v_count FROM acs_object_grantee_priv_map WHERE object_id = permission_p.object_id AND privilege = permission_p.privilege AND grantee_id IN (SELECT DISTINCT segment_id FROM rel_seg_approved_member_map WHERE member_id = permission_p.party_id); if v_count > 0 then return 't'; end if; -- return 'f'; end; -- end acs_permission; / show errors
The big bottleneck was the performance of the group and group-rels related permission checks, which is now much better. Everything seems to work great now, but am I missing something?