Skip to content

Commit 98cee42

Browse files
authored
Merge pull request #10 from ParvLab/readme
Readme
2 parents 8ec5801 + 5553bc0 commit 98cee42

17 files changed

Lines changed: 2294 additions & 6 deletions

File tree

crates/aegis-core/Cargo.toml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,26 @@ name = "partition"
8383
harness = false
8484
path = "benches/partition.rs"
8585

86+
[[bench]]
87+
name = "list"
88+
harness = false
89+
path = "benches/list.rs"
90+
91+
[[bench]]
92+
name = "write"
93+
harness = false
94+
path = "benches/write.rs"
95+
96+
[[bench]]
97+
name = "explain"
98+
harness = false
99+
path = "benches/explain.rs"
100+
101+
[[bench]]
102+
name = "memory"
103+
harness = false
104+
path = "benches/memory.rs"
105+
86106
[features]
87107
default = ["sqlite"]
88108
sqlite = ["dep:rusqlite", "dep:r2d2", "dep:r2d2_sqlite"]
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
use criterion::{Criterion, black_box, criterion_group, criterion_main};
2+
3+
use aegis_core::engine::GraphEngine;
4+
use aegis_core::storage::StorageBackend;
5+
use aegis_core::storage::sqlite::{SqliteConfig, SqliteStorage};
6+
use aegis_core::types::schema::{PermissionDef, RelationDef, Schema, TypeDef};
7+
use aegis_core::types::*;
8+
use std::collections::HashMap;
9+
10+
fn setup_engine() -> GraphEngine {
11+
let schema = Schema {
12+
schema_version: 1,
13+
namespace: "bench".to_string(),
14+
types: {
15+
let mut types = HashMap::new();
16+
let mut relations = HashMap::new();
17+
relations.insert(
18+
"owner".to_string(),
19+
RelationDef {
20+
inherit_from: vec![],
21+
description: None,
22+
},
23+
);
24+
relations.insert(
25+
"viewer".to_string(),
26+
RelationDef {
27+
inherit_from: vec![],
28+
description: None,
29+
},
30+
);
31+
let mut permissions = HashMap::new();
32+
permissions.insert(
33+
"read".to_string(),
34+
PermissionDef {
35+
union_of: vec!["viewer".to_string(), "owner".to_string()],
36+
..Default::default()
37+
},
38+
);
39+
types.insert(
40+
"repo".to_string(),
41+
TypeDef {
42+
relations,
43+
permissions,
44+
..Default::default()
45+
},
46+
);
47+
types
48+
},
49+
};
50+
let mut storage = SqliteStorage::new(SqliteConfig::in_memory()).unwrap();
51+
storage.initialize().unwrap();
52+
let engine = GraphEngine::new(Box::new(storage), schema);
53+
54+
for i in 0..1000 {
55+
let subject = SubjectId::new(format!("user:{}", i)).unwrap();
56+
let repo = ResourceId::new(format!("repo:bench{}", i)).unwrap();
57+
engine
58+
.write(&RelationshipTuple::new(
59+
subject,
60+
Relation::new("owner").unwrap(),
61+
repo,
62+
))
63+
.unwrap();
64+
}
65+
66+
// Hierarchy: subjects owned by other subjects (chain of viewer relations)
67+
for i in 1..500 {
68+
let owner = SubjectId::new(format!("user:{}", i - 1)).unwrap();
69+
let member = ResourceId::new(format!("user:{}", i)).unwrap();
70+
engine
71+
.write(&RelationshipTuple::new(
72+
owner,
73+
Relation::new("viewer").unwrap(),
74+
member,
75+
))
76+
.unwrap();
77+
}
78+
79+
engine
80+
}
81+
82+
fn bench_explain_direct(c: &mut Criterion) {
83+
let engine = setup_engine();
84+
let subject = SubjectId::new("user:0").unwrap();
85+
let resource = ResourceId::new("repo:bench0").unwrap();
86+
87+
c.bench_function("explain_direct", |b| {
88+
b.iter(|| {
89+
let result = engine.explain(black_box(&subject), "read", black_box(&resource), None);
90+
black_box(result)
91+
})
92+
});
93+
}
94+
95+
fn bench_explain_missing(c: &mut Criterion) {
96+
let engine = setup_engine();
97+
let subject = SubjectId::new("user:9999").unwrap();
98+
let resource = ResourceId::new("repo:nonexistent").unwrap();
99+
100+
c.bench_function("explain_missing", |b| {
101+
b.iter(|| {
102+
let result = engine.explain(black_box(&subject), "read", black_box(&resource), None);
103+
black_box(result)
104+
})
105+
});
106+
}
107+
108+
criterion_group!(benches, bench_explain_direct, bench_explain_missing);
109+
criterion_main!(benches);

crates/aegis-core/benches/list.rs

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
use criterion::{Criterion, black_box, criterion_group, criterion_main};
2+
3+
use aegis_core::engine::GraphEngine;
4+
use aegis_core::storage::sqlite::{SqliteConfig, SqliteStorage};
5+
use aegis_core::storage::{StorageBackend, TupleFilter};
6+
use aegis_core::types::schema::{PermissionDef, RelationDef, Schema, TypeDef};
7+
use aegis_core::types::*;
8+
use std::collections::HashMap;
9+
10+
fn setup_engine() -> GraphEngine {
11+
let schema = Schema {
12+
schema_version: 1,
13+
namespace: "bench".to_string(),
14+
types: {
15+
let mut types = HashMap::new();
16+
let mut relations = HashMap::new();
17+
relations.insert(
18+
"owner".to_string(),
19+
RelationDef {
20+
inherit_from: vec![],
21+
description: None,
22+
},
23+
);
24+
relations.insert(
25+
"viewer".to_string(),
26+
RelationDef {
27+
inherit_from: vec![],
28+
description: None,
29+
},
30+
);
31+
let mut permissions = HashMap::new();
32+
permissions.insert(
33+
"read".to_string(),
34+
PermissionDef {
35+
union_of: vec!["viewer".to_string(), "owner".to_string()],
36+
..Default::default()
37+
},
38+
);
39+
types.insert(
40+
"repo".to_string(),
41+
TypeDef {
42+
relations,
43+
permissions,
44+
..Default::default()
45+
},
46+
);
47+
types
48+
},
49+
};
50+
let mut storage = SqliteStorage::new(SqliteConfig::in_memory()).unwrap();
51+
storage.initialize().unwrap();
52+
let engine = GraphEngine::new(Box::new(storage), schema);
53+
54+
for i in 0..1000 {
55+
let subject = SubjectId::new(format!("user:{}", i)).unwrap();
56+
let repo = ResourceId::new(format!("repo:list{}", i)).unwrap();
57+
engine
58+
.write(&RelationshipTuple::new(
59+
subject,
60+
Relation::new("owner").unwrap(),
61+
repo,
62+
))
63+
.unwrap();
64+
}
65+
66+
let resource = ResourceId::new("repo:populated").unwrap();
67+
for i in 0..100 {
68+
let subject = SubjectId::new(format!("user:pop{}", i)).unwrap();
69+
engine
70+
.write(&RelationshipTuple::new(
71+
subject,
72+
Relation::new("viewer").unwrap(),
73+
resource.clone(),
74+
))
75+
.unwrap();
76+
}
77+
78+
let subject = SubjectId::new("user:manyrels").unwrap();
79+
for i in 0..50 {
80+
let repo = ResourceId::new(format!("repo:many{}", i)).unwrap();
81+
engine
82+
.write(&RelationshipTuple::new(
83+
subject.clone(),
84+
Relation::new("owner").unwrap(),
85+
repo,
86+
))
87+
.unwrap();
88+
}
89+
engine
90+
}
91+
92+
fn bench_list_by_object(c: &mut Criterion) {
93+
let engine = setup_engine();
94+
let resource = ResourceId::new("repo:populated").unwrap();
95+
96+
c.bench_function("list_by_object", |b| {
97+
b.iter(|| {
98+
let result = engine.list_by_object(black_box(&resource), None, None);
99+
black_box(result)
100+
})
101+
});
102+
}
103+
104+
fn bench_list_by_subject(c: &mut Criterion) {
105+
let engine = setup_engine();
106+
let subject = SubjectId::new("user:manyrels").unwrap();
107+
108+
c.bench_function("list_by_subject", |b| {
109+
b.iter(|| {
110+
let result = engine.list_by_subject(black_box(&subject), None, None);
111+
black_box(result)
112+
})
113+
});
114+
}
115+
116+
fn bench_list_pagination(c: &mut Criterion) {
117+
let engine = setup_engine();
118+
let filter = TupleFilter::default();
119+
let pagination = PaginationParams::new(10, None);
120+
121+
c.bench_function("list_pagination", |b| {
122+
b.iter(|| {
123+
let result = engine.query(black_box(&filter), black_box(&pagination), None);
124+
black_box(result)
125+
})
126+
});
127+
}
128+
129+
fn bench_list_pagination_cursor(c: &mut Criterion) {
130+
let engine = setup_engine();
131+
let filter = TupleFilter::default();
132+
let first_page = engine
133+
.query(&filter, &PaginationParams::new(10, None), None)
134+
.unwrap();
135+
let cursor = first_page.next_cursor.unwrap();
136+
137+
c.bench_function("list_pagination_cursor", |b| {
138+
b.iter(|| {
139+
let pagination = PaginationParams::new(10, Some(black_box(cursor.clone())));
140+
let result = engine.query(black_box(&filter), black_box(&pagination), None);
141+
black_box(result)
142+
})
143+
});
144+
}
145+
146+
criterion_group!(
147+
benches,
148+
bench_list_by_object,
149+
bench_list_by_subject,
150+
bench_list_pagination,
151+
bench_list_pagination_cursor,
152+
);
153+
criterion_main!(benches);

0 commit comments

Comments
 (0)