1+ //! # Local Cache Management for CernVM-FS
2+ //!
3+ //! This module provides functionality for managing the local cache of CernVM-FS objects.
4+ //! The cache stores downloaded repository objects to improve performance and allow
5+ //! offline access to previously accessed content.
6+ //!
7+ //! ## Cache Structure
8+ //!
9+ //! The cache follows a two-level directory structure:
10+ //! - The main cache directory contains a `data` subdirectory
11+ //! - Inside `data`, objects are organized into 256 subdirectories (00-ff) based on
12+ //! the first two hex characters of their content hash
13+ //!
14+ //! ## Cache Operations
15+ //!
16+ //! The cache supports the following operations:
17+ //! - Initialization: Creating the directory structure
18+ //! - Adding: Determining the path where a file should be stored
19+ //! - Retrieval: Looking up files by their identifier
20+ //! - Eviction: Clearing the cache and rebuilding the structure
21+
122use std:: fs:: { create_dir_all, remove_dir_all} ;
223use std:: path:: { Path , PathBuf } ;
324
425use crate :: common:: { CvmfsError , CvmfsResult } ;
526
27+ /// A cache for storing repository objects locally
28+ ///
29+ /// The `Cache` struct manages a local directory structure where CernVM-FS objects
30+ /// are stored. It provides methods for initialization, file lookup, and cache management.
631#[ derive( Debug , Clone ) ]
732pub struct Cache {
33+ /// The root directory where cache files are stored.
834 pub cache_directory : String ,
935}
1036
1137impl Cache {
38+ /// Creates a new cache instance with the specified root directory.
39+ ///
40+ /// This constructor creates a new cache that will store files in the specified
41+ /// directory. It validates that the path can be properly represented as a string.
42+ ///
43+ /// # Arguments
44+ ///
45+ /// * `cache_directory` - The path to the root cache directory.
46+ ///
47+ /// # Returns
48+ ///
49+ /// Returns a `CvmfsResult<Self>` containing the new cache instance, or an error
50+ /// if the path is invalid.
51+ ///
52+ /// # Errors
53+ ///
54+ /// Returns `CvmfsError::FileNotFound` if the path cannot be converted to a string.
1255 pub fn new ( cache_directory : String ) -> CvmfsResult < Self > {
1356 let path = Path :: new ( & cache_directory) ;
1457 Ok ( Self {
1558 cache_directory : path. to_str ( ) . ok_or ( CvmfsError :: FileNotFound ) ?. into ( ) ,
1659 } )
1760 }
1861
62+ /// Initializes the cache directory structure.
63+ ///
64+ /// This method creates the cache directory structure if it doesn't exist. It creates
65+ /// a `data` subdirectory with 256 subdirectories (00-ff) to store objects based on
66+ /// the first two hex characters of their hash.
67+ ///
68+ /// # Returns
69+ ///
70+ /// Returns `Ok(())` if initialization is successful, or an error if directory
71+ /// creation fails.
72+ ///
73+ /// # Errors
74+ ///
75+ /// Returns filesystem errors if directory creation fails, or path conversion errors.
1976 pub fn initialize ( & self ) -> CvmfsResult < ( ) > {
2077 let base_path = self . create_directory ( "data" ) ?;
2178 for i in 0x00 ..=0xff {
@@ -26,6 +83,24 @@ impl Cache {
2683 Ok ( ( ) )
2784 }
2885
86+ /// Creates a directory within the cache root
87+ ///
88+ /// This helper method creates a directory at the specified path relative to the
89+ /// cache root directory, ensuring all parent directories are created as needed.
90+ ///
91+ /// # Arguments
92+ ///
93+ /// * `path` - The relative path to create within the cache directory
94+ ///
95+ /// # Returns
96+ ///
97+ /// Returns a `CvmfsResult<String>` containing the full path to the created directory,
98+ /// or an error if directory creation or path conversion fails.
99+ ///
100+ /// # Errors
101+ ///
102+ /// Returns filesystem errors if directory creation fails, or `CvmfsError::FileNotFound`
103+ /// if the path cannot be converted to a string.
29104 fn create_directory ( & self , path : & str ) -> CvmfsResult < String > {
30105 let cache_full_path = Path :: new ( & self . cache_directory ) . join ( path) ;
31106 create_dir_all ( cache_full_path. clone ( ) ) ?;
@@ -35,10 +110,35 @@ impl Cache {
35110 . map_err ( |_| CvmfsError :: FileNotFound )
36111 }
37112
113+ /// Gets the path where a file would be stored in the cache
114+ ///
115+ /// This method determines the full path where a file with the given name would
116+ /// be stored in the cache, without checking if it actually exists.
117+ ///
118+ /// # Arguments
119+ ///
120+ /// * `file_name` - The name of the file
121+ ///
122+ /// # Returns
123+ ///
124+ /// Returns a `PathBuf` with the full path where the file would be stored.
38125 pub fn add ( & self , file_name : & str ) -> PathBuf {
39126 Path :: join ( self . cache_directory . as_ref ( ) , file_name)
40127 }
41128
129+ /// Retrieves the path to a file if it exists in the cache
130+ ///
131+ /// This method checks if a file with the given name exists in the cache and
132+ /// returns its path if found.
133+ ///
134+ /// # Arguments
135+ ///
136+ /// * `file_name` - The name of the file to look up
137+ ///
138+ /// # Returns
139+ ///
140+ /// Returns an `Option<PathBuf>` containing the path to the file if it exists,
141+ /// or `None` if the file is not in the cache.
42142 pub fn get ( & self , file_name : & str ) -> Option < PathBuf > {
43143 let path = self . add ( file_name) ;
44144 if path. exists ( ) || path. is_file ( ) {
@@ -47,6 +147,20 @@ impl Cache {
47147 None
48148 }
49149
150+ /// Clears the cache and re-initializes the directory structure.
151+ ///
152+ /// This method removes all cached objects by deleting and recreating the data
153+ /// directory structure. It's useful for clearing corrupted cache data or freeing
154+ /// disk space.
155+ ///
156+ /// # Returns
157+ ///
158+ /// Returns `Ok(())` if eviction is successful, or an error if directory removal
159+ /// or reinitialization fails.
160+ ///
161+ /// # Errors
162+ ///
163+ /// Returns filesystem errors if directory operations fail.
50164 pub fn evict ( & self ) -> CvmfsResult < ( ) > {
51165 let data_path = Path :: new ( & self . cache_directory ) . join ( "data" ) ;
52166 if data_path. exists ( ) && data_path. is_dir ( ) {
0 commit comments