From 2681e8f9081b4a0b32185391b56578dca6d351d7 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Sun, 6 Nov 2022 12:51:48 +0900 Subject: [PATCH] repo: use OnceCell instead of Mutex> to store index This is perfect use case of OnceCell per the safety comment in index(). --- lib/src/repo.rs | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/lib/src/repo.rs b/lib/src/repo.rs index e65b8079f..e9220d2a2 100644 --- a/lib/src/repo.rs +++ b/lib/src/repo.rs @@ -18,10 +18,11 @@ use std::fmt::{Debug, Formatter}; use std::io::ErrorKind; use std::ops::Deref; use std::path::{Path, PathBuf}; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use std::{fs, io}; use itertools::Itertools; +use once_cell::sync::OnceCell; use thiserror::Error; use crate::backend::{Backend, BackendError, ChangeId, CommitId}; @@ -96,7 +97,7 @@ pub struct ReadonlyRepo { operation: Operation, settings: RepoSettings, index_store: Arc, - index: Mutex>>, + index: OnceCell>, view: View, } @@ -152,7 +153,7 @@ impl ReadonlyRepo { operation: init_op, settings: repo_settings, index_store, - index: Mutex::new(None), + index: OnceCell::new(), view, })) } @@ -199,27 +200,15 @@ impl ReadonlyRepo { } pub fn index(&self) -> &Arc { - let mut locked_index = self.index.lock().unwrap(); - if locked_index.is_none() { - locked_index.replace( - self.index_store - .get_index_at_op(&self.operation, &self.store), - ); - } - let index: &Arc = locked_index.as_ref().unwrap(); - // Extend lifetime from that of mutex lock to that of self. Safe since we never - // change value once it's been set (except in `reindex()` but that - // requires a mutable reference). - let index: &Arc = unsafe { std::mem::transmute(index) }; - index + self.index.get_or_init(|| { + self.index_store + .get_index_at_op(&self.operation, &self.store) + }) } pub fn reindex(&mut self) -> &Arc { self.index_store.reinit(); - { - let mut locked_index = self.index.lock().unwrap(); - locked_index.take(); - } + self.index.take(); self.index() } @@ -436,7 +425,7 @@ impl RepoLoader { operation, settings: self.repo_settings.clone(), index_store: self.index_store.clone(), - index: Mutex::new(Some(index)), + index: OnceCell::with_value(index), view, }; Arc::new(repo) @@ -451,7 +440,7 @@ impl RepoLoader { operation, settings: self.repo_settings.clone(), index_store: self.index_store.clone(), - index: Mutex::new(None), + index: OnceCell::new(), view, }; Arc::new(repo)