openMSX
FilePoolCore.hh
Go to the documentation of this file.
1 #ifndef FILEPOOLCORE_HH
2 #define FILEPOOLCORE_HH
3 
4 #include "FileOperations.hh"
5 #include "ObjectPool.hh"
6 #include "MemBuffer.hh"
7 #include "SimpleHashSet.hh"
8 #include "sha1.hh"
9 #include "xxhash.hh"
10 #include <cassert>
11 #include <cstdint>
12 #include <ctime>
13 #include <functional>
14 #include <string>
15 #include <string_view>
16 #include <vector>
17 
18 namespace openmsx {
19 
20 class File;
21 
22 enum class FileType {
23  NONE = 0,
24  SYSTEM_ROM = 1, ROM = 2, DISK = 4, TAPE = 8
25 };
27  return static_cast<FileType>(int(x) | int(y));
28 }
30  return static_cast<FileType>(int(x) & int(y));
31 }
33  x = x | y;
34  return x;
35 }
36 
38 {
39 public:
40  struct Dir {
41  std::string_view path;
43  };
44  using Directories = std::vector<Dir>;
45 
46 public:
47  FilePoolCore(std::string filecache,
48  std::function<Directories()> getDirectories,
49  std::function<void(std::string_view)> reportProgress);
50  ~FilePoolCore();
51 
56  [[nodiscard]] File getFile(FileType fileType, const Sha1Sum& sha1sum);
57 
62  [[nodiscard]] Sha1Sum getSha1Sum(File& file);
63 
68  void abort() { stop = true; }
69 
70 private:
71  struct ScanProgress {
72  uint64_t lastTime;
73  unsigned amountScanned;
74  };
75 
76  struct Entry {
77  Entry(const Sha1Sum& s, time_t t, std::string_view f)
78  : filename(f), time(t), sum(s)
79  {
80  assert(time != Date::INVALID_TIME_T);
81  }
82  Entry(const Sha1Sum& s, const char* t, std::string_view f)
83  : filename(f), timeStr(t), sum(s)
84  {
85  assert(timeStr != nullptr);
86  }
87 
88  [[nodiscard]] time_t getTime();
89  void setTime(time_t t);
90 
91  // - At least one of 'timeStr' or 'time' is valid.
92  // - 'filename' and 'timeStr' are non-owning pointers.
93  std::string_view filename;
94  const char* timeStr = nullptr; // might be nullptr
95  time_t time = Date::INVALID_TIME_T;
96  Sha1Sum sum;
97  };
98 
99  using Pool = ObjectPool<Entry>;
100  using Index = Pool::Index;
101  using Sha1Index = std::vector<Index>; // sorted on sha1sum
102 
103  class FilenameIndexHelper {
104  public:
105  FilenameIndexHelper(const Pool& p) : pool(p) {}
106  [[nodiscard]] std::string_view get(std::string_view s) const { return s; }
107  [[nodiscard]] std::string_view get(Index idx) const { return pool[idx].filename; }
108  private:
109  const Pool& pool;
110  };
111  struct FilenameIndexHash : FilenameIndexHelper {
112  FilenameIndexHash(const Pool& p) : FilenameIndexHelper(p) {}
113  template<typename T> [[nodiscard]] auto operator()(T t) const {
114  XXHasher hasher;
115  return hasher(get(t));
116  }
117  };
118  struct FilenameIndexEqual : FilenameIndexHelper {
119  FilenameIndexEqual(const Pool& p) : FilenameIndexHelper(p) {}
120  template<typename T1, typename T2>
121  [[nodiscard]] bool operator()(T1 x, T2 y) const {
122  return get(x) == get(y);
123  }
124  };
125  // Hash indexed by filename, points to a full object in 'pool'
126  using FilenameIndex = SimpleHashSet<Index, Index(-1), FilenameIndexHash, FilenameIndexEqual>;
127 
128 private:
129  void insert(const Sha1Sum& sum, time_t time, const std::string& filename);
130  [[nodiscard]] Sha1Index::iterator getSha1Iterator(Index idx, Entry& entry);
131  void remove(Sha1Index::iterator it);
132  void remove(Index idx);
133  void remove(Index idx, Entry& entry);
134  bool adjustSha1(Sha1Index::iterator it, Entry& entry, const Sha1Sum& newSum);
135  bool adjustSha1(Index idx, Entry& entry, const Sha1Sum& newSum);
136 
137  void readSha1sums();
138  void writeSha1sums();
139 
140  [[nodiscard]] File getFromPool(const Sha1Sum& sha1sum);
141  [[nodiscard]] File scanDirectory(
142  const Sha1Sum& sha1sum,
143  const std::string& directory,
144  std::string_view poolPath,
145  ScanProgress& progress);
146  [[nodiscard]] File scanFile(
147  const Sha1Sum& sha1sum,
148  const std::string& filename,
149  const FileOperations::Stat& st,
150  std::string_view poolPath,
151  ScanProgress& progress);
152  [[nodiscard]] Sha1Sum calcSha1sum(File& file);
153  [[nodiscard]] std::pair<Index, Entry*> findInDatabase(std::string_view filename);
154 
155 private:
156  std::string filecache; // path of the '.filecache' file.
157  std::function<Directories()> getDirectories;
158  std::function<void(std::string_view)> reportProgress;
159 
160  MemBuffer<char> fileMem; // content of initial .filecache
161  std::vector<std::string> stringBuffer; // owns strings that are not in 'fileMem'
162 
163  Pool pool; // the actual entries
164  Sha1Index sha1Index; // entries accessible via sha1, sorted on 'CompareSha1'
165  FilenameIndex filenameIndex{FilenameIndexHash(pool), FilenameIndexEqual(pool)}; // accessible via filename
166 
167  bool stop = false; // abort long search (set via reportProgress callback)
168  bool needWrite = false; // dirty '.filecache'? write on exit
169 
170  friend struct GetSha1;
171 };
172 
173 } // namespace openmsx
174 
175 #endif
TclObject t
Sha1Sum getSha1Sum(File &file)
Calculate sha1sum for the given File object.
FilePoolCore(std::string filecache, std::function< Directories()> getDirectories, std::function< void(std::string_view)> reportProgress)
Definition: FilePoolCore.cc:24
File getFile(FileType fileType, const Sha1Sum &sha1sum)
Search file with the given sha1sum.
void abort()
This is only meaningful to call from within the 'reportProgress' callback (constructor parameter).
Definition: FilePoolCore.hh:68
std::vector< Dir > Directories
Definition: FilePoolCore.hh:44
This class represents the result of a sha1 calculation (a 160-bit value).
Definition: sha1.hh:22
constexpr time_t INVALID_TIME_T
Definition: Date.hh:10
uint64_t getTime()
Get current (real) time in us.
Definition: Timer.cc:7
This file implemented 3 utility functions:
Definition: Autofire.cc:9
const T & get(const Event &event)
Definition: Event.hh:725
FileType operator&(FileType x, FileType y)
Definition: FilePoolCore.hh:29
constexpr const char *const filename
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:118
FileType operator|(FileType x, FileType y)
Definition: FilePoolCore.hh:26
FileType & operator|=(FileType &x, FileType y)
Definition: FilePoolCore.hh:32
auto sum(InputRange &&range, Proj proj={})
Definition: stl.hh:245