Skip to content

Commit 21c214b

Browse files
committed
perf(storage_mapping): Use oc_filecache.path_hash which is covered by an index
Signed-off-by: provokateurin <kate@provokateurin.de>
1 parent 4df1714 commit 21c214b

File tree

4 files changed

+30
-8
lines changed

4 files changed

+30
-8
lines changed

Cargo.lock

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ nextcloud-config-parser = "0.14.1"
3333
url = "2.5.4"
3434
clap = { version = "4.5.43", features = ["derive"] }
3535
sd-notify = { version = "0.4.5", optional = true }
36+
md5 = "0.8.0"
3637

3738
[dev-dependencies]
3839
mini-redis = "0.4.1"

src/storage_mapping.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use ahash::RandomState;
1010
use dashmap::mapref::one::Ref;
1111
use dashmap::DashMap;
1212
use log::debug;
13+
use md5;
1314
use rand::{thread_rng, Rng};
1415
use sqlx::any::AnyConnectOptions;
1516
use sqlx::{query_as, Any, AnyPool, FromRow};
@@ -20,8 +21,8 @@ use tokio::time::Duration;
2021
pub struct UserStorageAccess {
2122
#[sqlx(rename = "user_id")]
2223
user: UserId,
23-
#[sqlx(rename = "path")]
24-
root: String,
24+
#[sqlx(rename = "path_hash")]
25+
root_hash: String,
2526
}
2627

2728
struct CachedAccess {
@@ -86,12 +87,25 @@ impl StorageMapping {
8687
storage: u32,
8788
path: &str,
8889
) -> Result<impl Iterator<Item = UserId>, DatabaseError> {
90+
let parents: DashMap<String, ()> = DashMap::new();
91+
parents.insert(format!("{:x}", md5::compute("")), ());
92+
93+
let mut current_path = "".to_string();
94+
for name in path.split("/") {
95+
if current_path.is_empty() {
96+
current_path = name.to_string();
97+
} else {
98+
current_path = format!("{}/{}", current_path.clone(), name);
99+
}
100+
parents.insert(format!("{:x}", md5::compute(&current_path)), ());
101+
}
102+
89103
let cached = self.get_storage_mapping(storage).await?;
90104
Ok(cached
91105
.access
92106
.iter()
93107
.filter_map(move |access| {
94-
if path.starts_with(&access.root) {
108+
if parents.contains_key(&access.root_hash) {
95109
Some(access.user.clone())
96110
} else {
97111
None
@@ -108,7 +122,7 @@ impl StorageMapping {
108122
debug!("querying storage mapping for {storage}");
109123
let users = query_as::<Any, UserStorageAccess>(&format!(
110124
"\
111-
SELECT user_id, path \
125+
SELECT user_id, path_hash \
112126
FROM {prefix}mounts \
113127
INNER JOIN {prefix}filecache ON root_id = fileid \
114128
WHERE storage_id = {storage}",

tests/integration.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl Services {
8282
.await
8383
.expect("Failed to connect sqlite database");
8484

85-
sqlx::query("CREATE TABLE oc_filecache(fileid BIGINT, path TEXT)")
85+
sqlx::query("CREATE TABLE oc_filecache(fileid BIGINT, path_hash TEXT)")
8686
.execute(&db)
8787
.await
8888
.unwrap();
@@ -237,9 +237,9 @@ impl Services {
237237
}
238238

239239
async fn add_filecache_item(&self, fileid: u32, path: &str) {
240-
sqlx::query("INSERT INTO oc_filecache(fileid, path) VALUES(?, ?)")
240+
sqlx::query("INSERT INTO oc_filecache(fileid, path_hash) VALUES(?, ?)")
241241
.bind(fileid as i64)
242-
.bind(path)
242+
.bind(format!("{:x}", md5::compute(path)))
243243
.execute(&self.db)
244244
.await
245245
.unwrap();

0 commit comments

Comments
 (0)