Skip to content

Commit cbeed65

Browse files
feat: Basic model speedup (#245)
* feat: [basic_model_speedup] option to use unordered_set<vector> instead of vector<vector> for policies storage * feat: [basic_model_speedup] ability unordered_set / vector be used as base collection on compilation * feat: [basic_model_speedup] expalin work with collection * feat: [basic_model_speedup] using hashes instead of vectors for basic model (allow) on enforcement * feat: [basic_model_speedup] new fare benchmark for large basic model * feat: [basic_model_speedup] cmake option to compile vector/unordered_set policy storage * feat: [basic_model_speedup] filter test fix * feat: [basic_model_speedup] new policy_collection that abstract vector/unordered_set * feat: [basic_model_speedup] automatic usage of hashset when appropriated * feat: [basic_model_speedup] automatic detection of hash usage without compilation option * feat: [basic_model_speedup] CI fixes for linux * feat: [basic_model_speedup] CI fix for Windows
1 parent 4deab3b commit cbeed65

38 files changed

+714
-267
lines changed

casbin/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ set(CASBIN_SOURCE_FILES
1616
enforcer.cpp
1717
enforcer_cached.cpp
1818
enforcer_synced.cpp
19+
selected_policies.cpp
1920
internal_api.cpp
2021
logger.cpp
2122
management_api.cpp
@@ -42,6 +43,7 @@ set(CASBIN_SOURCE_FILES
4243
model/function.cpp
4344
model/model.cpp
4445
model/evaluator.cpp
46+
model/policy_collection.cpp
4547
persist/file_adapter/batch_file_adapter.cpp
4648
persist/file_adapter/file_adapter.cpp
4749
persist/file_adapter/filtered_file_adapter.cpp

casbin/enforcer.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,17 @@
2020
#define ENFORCER_CPP
2121

2222
#include <algorithm>
23+
#include <regex>
2324

2425
#include "casbin/effect/default_effector.h"
2526
#include "casbin/enforcer.h"
27+
#include "casbin/selected_policies.h"
2628
#include "casbin/exception/casbin_adapter_exception.h"
2729
#include "casbin/exception/casbin_enforcer_exception.h"
2830
#include "casbin/persist/file_adapter/batch_file_adapter.h"
2931
#include "casbin/persist/file_adapter/file_adapter.h"
3032
#include "casbin/persist/watcher_ex.h"
33+
#include "casbin/model/policy_collection.hpp"
3134
#include "casbin/rbac/default_role_manager.h"
3235
#include "casbin/util/util.h"
3336

@@ -90,15 +93,15 @@ bool Enforcer::m_enforce(const std::string& matcher, std::vector<std::string>& e
9093
Effect effect;
9194
int explainIndex;
9295

93-
std::vector<std::vector<std::string>>& p_policy = m_model->m["p"].assertion_map["p"]->policy;
96+
SelectedPolicies selected_policies(evalator, matcher, m_model);
97+
PoliciesValues& p_policy = *selected_policies;
9498

9599
if (auto policy_len = p_policy.size(); policy_len != 0) {
96100
policy_effects = std::vector<Effect>(policy_len, Effect::Indeterminate);
97101
matcher_results = std::vector<float>(policy_len, 0.0f);
98102

99-
for (int policy_index = 0; policy_index < policy_len; policy_index++) {
100-
std::vector<std::string>& p_vals = m_model->m["p"].assertion_map["p"]->policy[policy_index];
101-
103+
int policy_index = 0;
104+
for (auto& p_vals : p_policy ) {
102105
casbin::LogUtil::LogPrint("Policy Rule: ", p_vals);
103106
if (p_tokens.size() != p_vals.size()) {
104107
throw CasbinEnforcerException("invalid policy size");
@@ -174,6 +177,7 @@ bool Enforcer::m_enforce(const std::string& matcher, std::vector<std::string>& e
174177
if (effect != Effect::Indeterminate) {
175178
break;
176179
}
180+
policy_index++;
177181
}
178182

179183
casbin::LogUtil::LogPrint("Rule Results: ", policy_effects);
@@ -214,12 +218,12 @@ bool Enforcer::m_enforce(const std::string& matcher, std::vector<std::string>& e
214218
casbin::LogUtil::LogPrint("Rule Results: ", policy_effects);
215219
}
216220

217-
std::vector<std::vector<std::string>> logExplains;
221+
PoliciesValues logExplains;
218222

219-
logExplains.push_back(explains);
223+
logExplains.emplace(explains);
220224
if (explainIndex != -1 && (p_policy.size() > explainIndex)) {
221-
explains = p_policy[explainIndex];
222-
logExplains.push_back(explains);
225+
explains = *std::next(p_policy.begin(), explainIndex);
226+
logExplains.emplace(explains);
223227
}
224228

225229
// effect --> result
@@ -228,9 +232,6 @@ bool Enforcer::m_enforce(const std::string& matcher, std::vector<std::string>& e
228232
result = true;
229233
}
230234

231-
// TODO
232-
// m_log.LogPrint(exp_string, evalator, result, logExplains);
233-
234235
return result;
235236
}
236237

@@ -508,7 +509,7 @@ void Enforcer::BuildRoleLinks() {
508509
}
509510

510511
// BuildIncrementalRoleLinks provides incremental build the role inheritance relations.
511-
void Enforcer::BuildIncrementalRoleLinks(policy_op op, const std::string& p_type, const std::vector<std::vector<std::string>>& rules) {
512+
void Enforcer::BuildIncrementalRoleLinks(policy_op op, const std::string& p_type, const PoliciesValues& rules) {
512513
return m_model->BuildIncrementalRoleLinks(this->rm, op, "g", p_type, rules);
513514
}
514515

casbin/enforcer_synced.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -280,43 +280,43 @@ std::vector<std::string> SyncedEnforcer ::GetAllNamedRoles(const std::string& pt
280280
}
281281

282282
// GetPolicy gets all the authorization rules in the policy.
283-
std::vector<std::vector<std::string>> SyncedEnforcer ::GetPolicy() {
283+
PoliciesValues SyncedEnforcer ::GetPolicy() {
284284
std::shared_lock<std::shared_mutex> lock(policyMutex);
285285
return Enforcer::GetPolicy();
286286
}
287287

288288
// GetNamedPolicy gets all the authorization rules in the name:x::d policy.
289-
std::vector<std::vector<std::string>> SyncedEnforcer ::GetNamedPolicy(const std::string& ptype) {
289+
PoliciesValues SyncedEnforcer ::GetNamedPolicy(const std::string& ptype) {
290290
std::shared_lock<std::shared_mutex> lock(policyMutex);
291291
return Enforcer::GetNamedPolicy(ptype);
292292
}
293293

294294
// GetFilteredNamedPolicy gets all the authorization rules in the named policy, field filters can be specified.
295-
std::vector<std::vector<std::string>> SyncedEnforcer ::GetFilteredNamedPolicy(const std::string& ptype, int fieldIndex, const std::vector<std::string>& fieldValues) {
295+
PoliciesValues SyncedEnforcer ::GetFilteredNamedPolicy(const std::string& ptype, int fieldIndex, const std::vector<std::string>& fieldValues) {
296296
std::shared_lock<std::shared_mutex> lock(policyMutex);
297297
return Enforcer::GetFilteredNamedPolicy(ptype, fieldIndex, fieldValues);
298298
}
299299

300300
// GetGroupingPolicy gets all the role inheritance rules in the policy.
301-
std::vector<std::vector<std::string>> SyncedEnforcer ::GetGroupingPolicy() {
301+
PoliciesValues SyncedEnforcer ::GetGroupingPolicy() {
302302
std::shared_lock<std::shared_mutex> lock(policyMutex);
303303
return Enforcer::GetGroupingPolicy();
304304
}
305305

306306
// GetFilteredGroupingPolicy gets all the role inheritance rules in the policy, field filters can be specified.
307-
std::vector<std::vector<std::string>> SyncedEnforcer ::GetFilteredGroupingPolicy(int fieldIndex, const std::vector<std::string>& fieldValues) {
307+
PoliciesValues SyncedEnforcer ::GetFilteredGroupingPolicy(int fieldIndex, const std::vector<std::string>& fieldValues) {
308308
std::shared_lock<std::shared_mutex> lock(policyMutex);
309309
return Enforcer::GetFilteredGroupingPolicy(fieldIndex, fieldValues);
310310
}
311311

312312
// GetNamedGroupingPolicy gets all the role inheritance rules in the policy.
313-
std::vector<std::vector<std::string>> SyncedEnforcer ::GetNamedGroupingPolicy(const std::string& ptype) {
313+
PoliciesValues SyncedEnforcer ::GetNamedGroupingPolicy(const std::string& ptype) {
314314
std::shared_lock<std::shared_mutex> lock(policyMutex);
315315
return Enforcer::GetNamedGroupingPolicy(ptype);
316316
}
317317

318318
// GetFilteredNamedGroupingPolicy gets all the role inheritance rules in the policy, field filters can be specified.
319-
std::vector<std::vector<std::string>> SyncedEnforcer ::GetFilteredNamedGroupingPolicy(const std::string& ptype, int fieldIndex, const std::vector<std::string>& fieldValues) {
319+
PoliciesValues SyncedEnforcer ::GetFilteredNamedGroupingPolicy(const std::string& ptype, int fieldIndex, const std::vector<std::string>& fieldValues) {
320320
std::shared_lock<std::shared_mutex> lock(policyMutex);
321321
return Enforcer::GetFilteredNamedGroupingPolicy(ptype, fieldIndex, fieldValues);
322322
}
@@ -344,7 +344,7 @@ bool SyncedEnforcer ::AddPolicy(const std::vector<std::string>& params) {
344344
// AddPolicies adds authorization rules to the current policy.
345345
// If the rule already exists, the function returns false for the corresponding rule and the rule will not be added.
346346
// Otherwise the function returns true for the corresponding rule by adding the new rule.
347-
bool SyncedEnforcer ::AddPolicies(const std::vector<std::vector<std::string>>& rules) {
347+
bool SyncedEnforcer ::AddPolicies(const PoliciesValues& rules) {
348348
std::unique_lock<std::shared_mutex> lock(policyMutex);
349349
return Enforcer::AddPolicies(rules);
350350
}
@@ -360,7 +360,7 @@ bool SyncedEnforcer ::AddNamedPolicy(const std::string& ptype, const std::vector
360360
// AddNamedPolicies adds authorization rules to the current named policy.
361361
// If the rule already exists, the function returns false for the corresponding rule and the rule will not be added.
362362
// Otherwise the function returns true for the corresponding by adding the new rule.
363-
bool SyncedEnforcer ::AddNamedPolicies(const std::string& ptype, const std::vector<std::vector<std::string>>& rules) {
363+
bool SyncedEnforcer ::AddNamedPolicies(const std::string& ptype, const PoliciesValues& rules) {
364364
std::unique_lock<std::shared_mutex> lock(policyMutex);
365365
return Enforcer::AddNamedPolicies(ptype, rules);
366366
}
@@ -383,18 +383,18 @@ bool SyncedEnforcer ::UpdateNamedPolicy(const std::string& ptype, const std::vec
383383
}
384384

385385
// UpdatePolicies updates authorization rules from the current policies.
386-
bool SyncedEnforcer ::UpdatePolicies(const std::vector<std::vector<std::string>>& oldPolices, const std::vector<std::vector<std::string>>& newPolicies) {
386+
bool SyncedEnforcer ::UpdatePolicies(const PoliciesValues& oldPolices, const PoliciesValues& newPolicies) {
387387
std::unique_lock<std::shared_mutex> lock(policyMutex);
388388
return Enforcer::UpdatePolicies(oldPolices, newPolicies);
389389
}
390390

391-
bool SyncedEnforcer ::UpdateNamedPolicies(const std::string& ptype, const std::vector<std::vector<std::string>>& p1, const std::vector<std::vector<std::string>>& p2) {
391+
bool SyncedEnforcer ::UpdateNamedPolicies(const std::string& ptype, const PoliciesValues& p1, const PoliciesValues& p2) {
392392
std::unique_lock<std::shared_mutex> lock(policyMutex);
393393
return Enforcer::UpdateNamedPolicies(ptype, p1, p2);
394394
}
395395

396396
// RemovePolicies removes authorization rules from the current policy.
397-
bool SyncedEnforcer ::RemovePolicies(const std::vector<std::vector<std::string>>& rules) {
397+
bool SyncedEnforcer ::RemovePolicies(const PoliciesValues& rules) {
398398
std::unique_lock<std::shared_mutex> lock(policyMutex);
399399
return Enforcer::RemovePolicies(rules);
400400
}
@@ -412,7 +412,7 @@ bool SyncedEnforcer ::RemoveNamedPolicy(const std::string& ptype, const std::vec
412412
}
413413

414414
// RemoveNamedPolicies removes authorization rules from the current named policy.
415-
bool SyncedEnforcer ::RemoveNamedPolicies(const std::string& ptype, const std::vector<std::vector<std::string>>& rules) {
415+
bool SyncedEnforcer ::RemoveNamedPolicies(const std::string& ptype, const PoliciesValues& rules) {
416416
std::unique_lock<std::shared_mutex> lock(policyMutex);
417417
return Enforcer::RemoveNamedPolicies(ptype, rules);
418418
}
@@ -446,7 +446,7 @@ bool SyncedEnforcer ::AddGroupingPolicy(const std::vector<std::string>& params)
446446
// AddGroupingPolicies adds role inheritance rulea to the current policy.
447447
// If the rule already exists, the function returns false for the corresponding policy rule and the rule will not be added.
448448
// Otherwise the function returns true for the corresponding policy rule by adding the new rule.
449-
bool SyncedEnforcer ::AddGroupingPolicies(const std::vector<std::vector<std::string>>& rules) {
449+
bool SyncedEnforcer ::AddGroupingPolicies(const PoliciesValues& rules) {
450450
std::unique_lock<std::shared_mutex> lock(policyMutex);
451451
return Enforcer::AddGroupingPolicies(rules);
452452
}
@@ -462,7 +462,7 @@ bool SyncedEnforcer ::AddNamedGroupingPolicy(const std::string& ptype, const std
462462
// AddNamedGroupingPolicies adds named role inheritance rules to the current policy.
463463
// If the rule already exists, the function returns false for the corresponding policy rule and the rule will not be added.
464464
// Otherwise the function returns true for the corresponding policy rule by adding the new rule.
465-
bool SyncedEnforcer ::AddNamedGroupingPolicies(const std::string& ptype, const std::vector<std::vector<std::string>>& rules) {
465+
bool SyncedEnforcer ::AddNamedGroupingPolicies(const std::string& ptype, const PoliciesValues& rules) {
466466
std::unique_lock<std::shared_mutex> lock(policyMutex);
467467
return Enforcer::AddNamedGroupingPolicies(ptype, rules);
468468
}
@@ -474,7 +474,7 @@ bool SyncedEnforcer ::RemoveGroupingPolicy(const std::vector<std::string>& param
474474
}
475475

476476
// RemoveGroupingPolicies removes role inheritance rules from the current policy.
477-
bool SyncedEnforcer ::RemoveGroupingPolicies(const std::vector<std::vector<std::string>>& rules) {
477+
bool SyncedEnforcer ::RemoveGroupingPolicies(const PoliciesValues& rules) {
478478
std::unique_lock<std::shared_mutex> lock(policyMutex);
479479
return Enforcer::RemoveGroupingPolicies(rules);
480480
}
@@ -492,7 +492,7 @@ bool SyncedEnforcer ::RemoveNamedGroupingPolicy(const std::string& ptype, const
492492
}
493493

494494
// RemoveNamedGroupingPolicies removes role inheritance rules from the current named policy.
495-
bool SyncedEnforcer ::RemoveNamedGroupingPolicies(const std::string& ptype, const std::vector<std::vector<std::string>>& rules) {
495+
bool SyncedEnforcer ::RemoveNamedGroupingPolicies(const std::string& ptype, const PoliciesValues& rules) {
496496
std::unique_lock<std::shared_mutex> lock(policyMutex);
497497
return Enforcer::RemoveNamedGroupingPolicies(ptype, rules);
498498
}

casbin/internal_api.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ bool Enforcer::addPolicy(const std::string& sec, const std::string& p_type, cons
3535
return rule_added;
3636

3737
if (sec == "g") {
38-
std::vector<std::vector<std::string>> rules{rule};
38+
PoliciesValues rules({rule});
3939
this->BuildIncrementalRoleLinks(policy_add, p_type, rules);
4040
}
4141

@@ -57,7 +57,7 @@ bool Enforcer::addPolicy(const std::string& sec, const std::string& p_type, cons
5757
}
5858

5959
// addPolicies adds rules to the current policy.
60-
bool Enforcer::addPolicies(const std::string& sec, const std::string& p_type, const std::vector<std::vector<std::string>>& rules) {
60+
bool Enforcer::addPolicies(const std::string& sec, const std::string& p_type, const PoliciesValues& rules) {
6161
bool rules_added = m_model->AddPolicies(sec, p_type, rules);
6262
if (!rules_added)
6363
return rules_added;
@@ -85,7 +85,7 @@ bool Enforcer::removePolicy(const std::string& sec, const std::string& p_type, c
8585
return rule_removed;
8686

8787
if (sec == "g") {
88-
std::vector<std::vector<std::string>> rules{rule};
88+
PoliciesValues rules({rule});
8989
this->BuildIncrementalRoleLinks(policy_add, p_type, rules);
9090
}
9191

@@ -107,7 +107,7 @@ bool Enforcer::removePolicy(const std::string& sec, const std::string& p_type, c
107107
}
108108

109109
// removePolicies removes rules from the current policy.
110-
bool Enforcer::removePolicies(const std::string& sec, const std::string& p_type, const std::vector<std::vector<std::string>>& rules) {
110+
bool Enforcer::removePolicies(const std::string& sec, const std::string& p_type, const PoliciesValues& rules) {
111111
bool rules_removed = m_model->AddPolicies(sec, p_type, rules);
112112
if (!rules_removed)
113113
return rules_removed;
@@ -130,9 +130,9 @@ bool Enforcer::removePolicies(const std::string& sec, const std::string& p_type,
130130

131131
// removeFilteredPolicy removes rules based on field filters from the current policy.
132132
bool Enforcer::removeFilteredPolicy(const std::string& sec, const std::string& p_type, int field_index, const std::vector<std::string>& field_values) {
133-
std::pair<int, std::vector<std::vector<std::string>>> p = m_model->RemoveFilteredPolicy(sec, p_type, field_index, field_values);
133+
std::pair<int, PoliciesValues> p = m_model->RemoveFilteredPolicy(sec, p_type, field_index, field_values);
134134
bool rule_removed = p.first;
135-
std::vector<std::vector<std::string>> effects = p.second;
135+
PoliciesValues effects = p.second;
136136

137137
if (!rule_removed)
138138
return rule_removed;
@@ -163,8 +163,8 @@ bool Enforcer::updatePolicy(const std::string& sec, const std::string& p_type, c
163163
return false;
164164

165165
if (sec == "g") {
166-
this->BuildIncrementalRoleLinks(policy_remove, p_type, {oldRule});
167-
this->BuildIncrementalRoleLinks(policy_add, p_type, {newRule});
166+
this->BuildIncrementalRoleLinks(policy_remove, p_type, PoliciesValues({oldRule}));
167+
this->BuildIncrementalRoleLinks(policy_add, p_type, PoliciesValues({newRule}));
168168
}
169169
if (m_watcher && m_auto_notify_watcher) {
170170
if (IsInstanceOf<WatcherUpdatable>(m_watcher.get())) {
@@ -176,7 +176,7 @@ bool Enforcer::updatePolicy(const std::string& sec, const std::string& p_type, c
176176
return is_rule_updated;
177177
}
178178

179-
bool Enforcer::updatePolicies(const std::string& sec, const std::string& p_type, const std::vector<std::vector<std::string>>& oldRules, const std::vector<std::vector<std::string>>& newRules) {
179+
bool Enforcer::updatePolicies(const std::string& sec, const std::string& p_type, const PoliciesValues& oldRules, const PoliciesValues& newRules) {
180180
bool is_rules_updated = m_model->UpdatePolicies(sec, p_type, oldRules, newRules);
181181
if (!is_rules_updated)
182182
return false;

0 commit comments

Comments
 (0)