LLDB  mainline
DataFileCache.h
Go to the documentation of this file.
1 //===-- DataFileCache.h -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_CORE_DATAFILECACHE_H
10 #define LLDB_CORE_DATAFILECACHE_H
11 
12 #include "lldb/Utility/FileSpec.h"
13 #include "lldb/Utility/Status.h"
14 #include "lldb/Utility/UUID.h"
15 #include "lldb/lldb-forward.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/Support/Caching.h"
18 #include <mutex>
19 
20 namespace lldb_private {
21 
22 /// This class enables data to be cached into a directory using the llvm
23 /// caching code. Data can be stored and accessed using a unique string key.
24 /// The data will be stored in the directory that is specified in the
25 /// DataFileCache constructor. The data will be stored in files that start with
26 /// "llvmcache-<key>" where <key> is the key name specified when getting to
27 /// setting cached data.
28 ///
29 /// Sample code for how to use the cache:
30 ///
31 /// DataFileCache cache("/tmp/lldb-test-cache");
32 /// StringRef key("Key1");
33 /// auto mem_buffer_up = cache.GetCachedData(key);
34 /// if (mem_buffer_up) {
35 /// printf("cached data:\n%s", mem_buffer_up->getBufferStart());
36 /// } else {
37 /// std::vector<uint8_t> data = { 'h', 'e', 'l', 'l', 'o', '\n' };
38 /// cache.SetCachedData(key, data);
39 /// }
40 
42 public:
43  /// Create a data file cache in the directory path that is specified.
44  ///
45  /// Data will be cached in files created in this directory when clients call
46  /// DataFileCache::SetCacheData.
47  DataFileCache(llvm::StringRef path);
48 
49  /// Get cached data from the cache directory for the specified key.
50  ///
51  /// Keys must be unique for any given data. This function attempts to see if
52  /// the data is available for the specified key and will return a valid memory
53  /// buffer is data is available.
54  ///
55  /// \param key
56  /// The unique string key that identifies data being cached.
57  ///
58  /// \return
59  /// A valid unique pointer to a memory buffer if the data is available, or
60  /// a unique pointer that contains NULL if the data is not available.
61  std::unique_ptr<llvm::MemoryBuffer> GetCachedData(llvm::StringRef key);
62 
63  /// Set cached data for the specified key.
64  ///
65  /// Setting the cached data will save a file in the cache directory to contain
66  /// the specified data.
67  ///
68  /// \param key
69  /// The unique string key that identifies data being cached.
70  ///
71  /// \return
72  /// True if the data was successfully cached, false otherwise.
73  bool SetCachedData(llvm::StringRef key, llvm::ArrayRef<uint8_t> data);
74 
75  /// Remove the cache file associated with the key.
76  Status RemoveCacheFile(llvm::StringRef key);
77 
78 private:
79  /// Return the cache file that is associated with the key.
80  FileSpec GetCacheFilePath(llvm::StringRef key);
81 
82  llvm::FileCache m_cache_callback;
84  std::mutex m_mutex;
85  std::unique_ptr<llvm::MemoryBuffer> m_mem_buff_up;
86  bool m_take_ownership = false;
87 };
88 
89 /// A signature for a given file on disk.
90 ///
91 /// Any files that are cached in the LLDB index cached need some data that
92 /// uniquely identifies a file on disk and this information should be written
93 /// into each cache file so we can validate if the cache file still matches
94 /// the file we are trying to load cached data for. Objects can fill out this
95 /// signature and then encode and decode them to validate the signatures
96 /// match. If they do not match, the cache file on disk should be removed as
97 /// it is out of date.
99  /// UUID of object file or module.
100  llvm::Optional<UUID> m_uuid = llvm::None;
101  /// Modification time of file on disk.
102  llvm::Optional<std::time_t> m_mod_time = llvm::None;
103  /// If this describes a .o file with a BSD archive, the BSD archive's
104  /// modification time will be in m_mod_time, and the .o file's modification
105  /// time will be in this m_obj_mod_time.
106  llvm::Optional<std::time_t> m_obj_mod_time = llvm::None;
107 
108  CacheSignature() = default;
109 
110  /// Create a signature from a module.
112 
113  /// Create a signature from an object file.
115 
116  void Clear() {
117  m_uuid = llvm::None;
118  m_mod_time = llvm::None;
119  m_obj_mod_time = llvm::None;
120  }
121 
122  /// Return true only if the CacheSignature is valid.
123  ///
124  /// Cache signatures are considered valid only if there is a UUID in the file
125  /// that can uniquely identify the file. Some build systems play with
126  /// modification times of file so we can not trust them without using valid
127  /// unique idenifier like the UUID being valid.
128  bool IsValid() const { return m_uuid.has_value(); }
129 
130  /// Check if two signatures are the same.
131  bool operator==(const CacheSignature &rhs) const {
132  return m_uuid == rhs.m_uuid && m_mod_time == rhs.m_mod_time &&
134  }
135 
136  /// Check if two signatures differ.
137  bool operator!=(const CacheSignature &rhs) const { return !(*this == rhs); }
138  /// Encode this object into a data encoder object.
139  ///
140  /// This allows this object to be serialized to disk. The CacheSignature
141  /// object must have at least one member variable that has a value in order to
142  /// be serialized so that we can match this data to when the cached file is
143  /// loaded at a later time.
144  ///
145  /// \param encoder
146  /// A data encoder object that serialized bytes will be encoded into.
147  ///
148  /// \return
149  /// True if a signature was encoded, and false if there were no member
150  /// variables that had value. False indicates this data should not be
151  /// cached to disk because we were unable to encode a valid signature.
152  bool Encode(DataEncoder &encoder) const;
153 
154  /// Decode a serialized version of this object from data.
155  ///
156  /// \param data
157  /// The decoder object that references the serialized data.
158  ///
159  /// \param offset_ptr
160  /// A pointer that contains the offset from which the data will be decoded
161  /// from that gets updated as data gets decoded.
162  ///
163  /// \return
164  /// True if the signature was successfully decoded, false otherwise.
165  bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr);
166 };
167 
168 /// Many cache files require string tables to store data efficiently. This
169 /// class helps create string tables.
171 public:
172  ConstStringTable() = default;
173  /// Add a string into the string table.
174  ///
175  /// Add a string to the string table will only add the same string one time
176  /// and will return the offset in the string table buffer to that string.
177  /// String tables are easy to build with ConstString objects since most LLDB
178  /// classes for symbol or debug info use them already and they provide
179  /// permanent storage for the string.
180  ///
181  /// \param s
182  /// The string to insert into the string table.
183  ///
184  /// \return
185  /// The byte offset from the start of the string table for the inserted
186  /// string. Duplicate strings that get inserted will return the same
187  /// byte offset.
189 
190  bool Encode(DataEncoder &encoder);
191 
192 private:
193  std::vector<ConstString> m_strings;
194  llvm::DenseMap<ConstString, uint32_t> m_string_to_offset;
195  /// Skip one byte to start the string table off with an empty string.
197 };
198 
199 /// Many cache files require string tables to store data efficiently. This
200 /// class helps give out strings from a string table that was read from a
201 /// cache file.
203 public:
204  StringTableReader() = default;
205 
206  llvm::StringRef Get(uint32_t offset) const;
207 
208  bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr);
209 
210 protected:
211  /// All of the strings in the string table are contained in m_data.
212  llvm::StringRef m_data;
213 };
214 
215 } // namespace lldb_private
216 
217 #endif // LLDB_CORE_DATAFILECACHE_H
lldb_private::ConstStringTable::Encode
bool Encode(DataEncoder &encoder)
Definition: DataFileCache.cpp:271
lldb_private::StringTableReader::StringTableReader
StringTableReader()=default
lldb_private::StringTableReader
Many cache files require string tables to store data efficiently.
Definition: DataFileCache.h:202
lldb_private::DataFileCache::DataFileCache
DataFileCache(llvm::StringRef path)
Create a data file cache in the directory path that is specified.
Definition: DataFileCache.cpp:22
lldb_private::DataFileCache::GetCachedData
std::unique_ptr< llvm::MemoryBuffer > GetCachedData(llvm::StringRef key)
Get cached data from the cache directory for the specified key.
Definition: DataFileCache.cpp:66
UUID.h
lldb_private::ConstStringTable
Many cache files require string tables to store data efficiently.
Definition: DataFileCache.h:170
lldb_private::CacheSignature::IsValid
bool IsValid() const
Return true only if the CacheSignature is valid.
Definition: DataFileCache.h:128
lldb_private::CacheSignature::m_obj_mod_time
llvm::Optional< std::time_t > m_obj_mod_time
If this describes a .o file with a BSD archive, the BSD archive's modification time will be in m_mod_...
Definition: DataFileCache.h:106
lldb_private::Module
Definition: Module.h:85
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
lldb_private::ConstStringTable::ConstStringTable
ConstStringTable()=default
lldb_private::CacheSignature::Decode
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr)
Decode a serialized version of this object from data.
Definition: DataFileCache.cpp:224
lldb_private::CacheSignature::Encode
bool Encode(DataEncoder &encoder) const
Encode this object into a data encoder object.
Definition: DataFileCache.cpp:202
lldb_private::ConstStringTable::Add
uint32_t Add(ConstString s)
Add a string into the string table.
Definition: DataFileCache.cpp:258
lldb_private::DataFileCache::SetCachedData
bool SetCachedData(llvm::StringRef key, llvm::ArrayRef< uint8_t > data)
Set cached data for the specified key.
Definition: DataFileCache.cpp:100
lldb_private::FileSpec
Definition: FileSpec.h:56
lldb_private::DataFileCache::m_mutex
std::mutex m_mutex
Definition: DataFileCache.h:84
lldb_private::DataFileCache::RemoveCacheFile
Status RemoveCacheFile(llvm::StringRef key)
Remove the cache file associated with the key.
Definition: DataFileCache.cpp:150
lldb_private::CacheSignature::CacheSignature
CacheSignature()=default
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::StringTableReader::Decode
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr)
Definition: DataFileCache.cpp:293
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::DataFileCache::m_mem_buff_up
std::unique_ptr< llvm::MemoryBuffer > m_mem_buff_up
Definition: DataFileCache.h:85
lldb_private::CacheSignature
A signature for a given file on disk.
Definition: DataFileCache.h:98
lldb_private::DataFileCache::m_take_ownership
bool m_take_ownership
Definition: DataFileCache.h:86
lldb_private::ConstStringTable::m_strings
std::vector< ConstString > m_strings
Definition: DataFileCache.h:193
lldb_private::DataFileCache::m_cache_callback
llvm::FileCache m_cache_callback
Definition: DataFileCache.h:82
lldb_private::CacheSignature::operator!=
bool operator!=(const CacheSignature &rhs) const
Check if two signatures differ.
Definition: DataFileCache.h:137
lldb_private::StringTableReader::m_data
llvm::StringRef m_data
All of the strings in the string table are contained in m_data.
Definition: DataFileCache.h:212
lldb_private::CacheSignature::Clear
void Clear()
Definition: DataFileCache.h:116
lldb_private::CacheSignature::m_mod_time
llvm::Optional< std::time_t > m_mod_time
Modification time of file on disk.
Definition: DataFileCache.h:102
lldb_private::CacheSignature::operator==
bool operator==(const CacheSignature &rhs) const
Check if two signatures are the same.
Definition: DataFileCache.h:131
lldb_private::Status
Definition: Status.h:44
uint32_t
lldb_private::DataFileCache::GetCacheFilePath
FileSpec GetCacheFilePath(llvm::StringRef key)
Return the cache file that is associated with the key.
Definition: DataFileCache.cpp:142
lldb_private::ConstStringTable::m_string_to_offset
llvm::DenseMap< ConstString, uint32_t > m_string_to_offset
Definition: DataFileCache.h:194
lldb-forward.h
lldb_private::DataFileCache
This class enables data to be cached into a directory using the llvm caching code.
Definition: DataFileCache.h:41
lldb_private::DataFileCache::m_cache_dir
FileSpec m_cache_dir
Definition: DataFileCache.h:83
Status.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::CacheSignature::m_uuid
llvm::Optional< UUID > m_uuid
UUID of object file or module.
Definition: DataFileCache.h:100
FileSpec.h
lldb_private::ConstStringTable::m_next_offset
uint32_t m_next_offset
Skip one byte to start the string table off with an empty string.
Definition: DataFileCache.h:196
lldb_private::ObjectFile
Definition: ObjectFile.h:60
lldb_private::StringTableReader::Get
llvm::StringRef Get(uint32_t offset) const
Definition: DataFileCache.cpp:309