1 //
2 // Copyright (c) 2010-2022 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 
8 using System.IO;
9 using System.Collections.Generic;
10 
11 namespace Antmicro.Renode.Utilities
12 {
13     public class SimpleFileCache
14     {
SimpleFileCache(string location, bool enabled = true)15         public SimpleFileCache(string location, bool enabled = true)
16         {
17             Enabled = enabled;
18             cacheLocation = Path.Combine(Emulator.UserDirectoryPath, location);
19 
20             internalCache = new HashSet<string>();
21             Populate();
22         }
23 
ContainsEntryWithSha(string sha)24         public bool ContainsEntryWithSha(string sha)
25         {
26             return Enabled && internalCache.Contains(sha);
27         }
28 
TryGetEntryWithSha(string sha, out string filename)29         public bool TryGetEntryWithSha(string sha, out string filename)
30         {
31             if(!Enabled || !ContainsEntryWithSha(sha))
32             {
33                 filename = null;
34                 return false;
35             }
36 
37             filename = Path.Combine(cacheLocation, sha);
38             return true;
39         }
40 
StoreEntryWithSha(string sha, string filename)41         public void StoreEntryWithSha(string sha, string filename)
42         {
43             if(!Enabled || ContainsEntryWithSha(sha))
44             {
45                 return;
46             }
47 
48             EnsureCacheDirectory();
49             using(var locker = new FileLocker(Path.Combine(cacheLocation, lockFileName)))
50             {
51                 FileCopier.Copy(filename, Path.Combine(cacheLocation, sha), true);
52                 internalCache.Add(sha);
53             }
54         }
55 
56         public bool Enabled { get; set; }
57 
Populate()58         private void Populate()
59         {
60             if(!Enabled)
61             {
62                 return;
63             }
64             EnsureCacheDirectory();
65             using(var locker = new FileLocker(Path.Combine(cacheLocation, lockFileName)))
66             {
67                 var dinfo = new DirectoryInfo(cacheLocation);
68                 foreach(var file in dinfo.EnumerateFiles())
69                 {
70                     internalCache.Add(file.Name);
71                 }
72             }
73         }
74 
EnsureCacheDirectory()75         private void EnsureCacheDirectory()
76         {
77             Directory.CreateDirectory(cacheLocation);
78         }
79 
80         private readonly HashSet<string> internalCache;
81         private readonly string cacheLocation;
82 
83         private const string lockFileName = ".lock";
84     }
85 }
86