From af1760b02ed40596032e1d2a96a6d16930b26956 Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Thu, 17 Dec 2020 22:57:41 -0800 Subject: [PATCH] index: load index file eagerly in Index::load() now that Repo::index() is lazy --- lib/src/index.rs | 49 ++++++++++++++++-------------------------------- lib/src/repo.rs | 14 ++++---------- 2 files changed, 20 insertions(+), 43 deletions(-) diff --git a/lib/src/index.rs b/lib/src/index.rs index 4aaf87e77..ed19493cc 100644 --- a/lib/src/index.rs +++ b/lib/src/index.rs @@ -20,7 +20,7 @@ use std::fs::File; use std::io; use std::io::{Cursor, Read, Write}; use std::path::{Path, PathBuf}; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use blake2::{Blake2b, Digest}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; @@ -1103,14 +1103,11 @@ impl IndexFile { } } -pub struct Index<'r> { - repo: &'r ReadonlyRepo, - dir: PathBuf, - op_id: Mutex, - index_file: Mutex>>, +pub struct Index { + index_file: Arc, } -impl Index<'_> { +impl Index { pub fn init(dir: PathBuf) { std::fs::create_dir(dir.join("operations")).unwrap(); } @@ -1121,39 +1118,25 @@ impl Index<'_> { } pub fn load(repo: &ReadonlyRepo, dir: PathBuf, op_id: OperationId) -> Index { + let op_id_hex = op_id.hex(); + let op_id_file = dir.join("operations").join(&op_id_hex); + let index_file = if op_id_file.exists() { + let op_id = OperationId(hex::decode(op_id_hex).unwrap()); + IndexFile::load_at_operation(&dir, repo.store().hash_length(), &op_id).unwrap() + } else { + let op = repo.view().get_operation(&op_id).unwrap(); + IndexFile::index(repo.store(), &dir, &op).unwrap() + }; + Index { - repo, - dir, - op_id: Mutex::new(op_id), - index_file: Mutex::new(None), + index_file: Arc::new(index_file), } } // TODO: Maybe just call this data() or something? We should also hide the // IndexFile type from the API. pub fn index_file(&self) -> Arc { - let mut locked_index_file = self.index_file.lock().unwrap(); - if locked_index_file.is_none() { - locked_index_file.replace(Arc::new(self.do_load())); - } - locked_index_file.as_ref().unwrap().clone() - } - - fn do_load(&self) -> IndexFile { - let op_id_hex = self.op_id.lock().unwrap().hex(); - let op_id_file = self.dir.join("operations").join(&op_id_hex); - if op_id_file.exists() { - let op_id = OperationId(hex::decode(op_id_hex).unwrap()); - IndexFile::load_at_operation(&self.dir, self.repo.store().hash_length(), &op_id) - .unwrap() - } else { - let op = self - .repo - .view() - .get_operation(&self.op_id.lock().unwrap()) - .unwrap(); - IndexFile::index(self.repo.store(), &self.dir, &op).unwrap() - } + self.index_file.clone() } } diff --git a/lib/src/repo.rs b/lib/src/repo.rs index 55342c63f..c89386db5 100644 --- a/lib/src/repo.rs +++ b/lib/src/repo.rs @@ -65,7 +65,7 @@ pub struct ReadonlyRepo { wc_path: PathBuf, store: Arc, settings: RepoSettings, - index: Mutex>>>, + index: Mutex>>, working_copy: Arc>, view: ReadonlyView, evolution: Option>, @@ -217,23 +217,17 @@ impl ReadonlyRepo { &self.wc_path } - pub fn index<'r>(&'r self) -> Arc> { + pub fn index(&self) -> Arc { let mut locked_index = self.index.lock().unwrap(); if locked_index.is_none() { - let repo_ref: &ReadonlyRepo = self; let op_id = self.view.base_op_head_id().clone(); - let static_lifetime_repo: &'static ReadonlyRepo = - unsafe { std::mem::transmute(repo_ref) }; locked_index.replace(Arc::new(Index::load( - static_lifetime_repo, + self, self.repo_path.join("index"), op_id, ))); } - let index: Arc> = locked_index.as_ref().unwrap().clone(); - // cast to lifetime of self - let index: Arc> = unsafe { std::mem::transmute(index) }; - index + locked_index.as_ref().unwrap().clone() } pub fn reindex(&mut self) -> Arc {