6#include <QtCore/QDirIterator>
7#include <QtCore/QStandardPaths>
9QGC_LOGGING_CATEGORY(ComponentInformationCacheLog,
"ComponentInformation.ComponentInformationCache")
12 : _path(path), _maxNumFiles(maxNumFiles)
14 initializeDirectory();
19 QString cacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1String(
"/QGCCompInfoCache");
24QString ComponentInformationCache::metaFileName(
const QString& fileTag)
26 return _path.filePath(fileTag+_metaExtension);
29QString ComponentInformationCache::dataFileName(
const QString& fileTag)
31 return _path.filePath(fileTag+_cacheExtension);
36 QFile meta(metaFileName(fileTag));
37 QFile data(dataFileName(fileTag));
38 if (!meta.exists() || !data.exists()) {
39 qCDebug(ComponentInformationCacheLog) <<
"Cache miss for" << fileTag;
43 qCDebug(ComponentInformationCacheLog) <<
"Cache hit for" << fileTag;
47 AccessCounterType previousCounter = -1;
48 if (meta.open(QIODevice::ReadWrite)) {
49 if (meta.read((
char*)&m,
sizeof(m)) ==
sizeof(m)) {
50 previousCounter = m.accessCounter;
51 m.accessCounter = _nextAccessCounter;
53 if (meta.write((
const char*)&m,
sizeof(m)) !=
sizeof(m)) {
54 qCWarning(ComponentInformationCacheLog) <<
"Meta write failed" << meta.fileName() << meta.errorString();
57 qCWarning(ComponentInformationCacheLog) <<
"Meta read failed" << meta.fileName() << meta.errorString();
61 qCWarning(ComponentInformationCacheLog) <<
"Failed to open" << meta.fileName() << meta.errorString();
64 _cachedFiles.remove(previousCounter);
65 _cachedFiles[_nextAccessCounter] = fileTag;
68 return data.fileName();
73 QFile meta(metaFileName(fileTag));
74 QFile data(dataFileName(fileTag));
75 QFile fileToCache(fileName);
76 if (meta.exists() || data.exists()) {
77 qCDebug(ComponentInformationCacheLog) <<
"Not inserting, entry already exists" << fileTag;
79 return data.fileName();
83 if (!fileToCache.rename(data.fileName())) {
84 qCDebug(ComponentInformationCacheLog) <<
"File rename failed from:to" << fileName << data.fileName() << fileToCache.errorString();
85 if (!fileToCache.copy(data.fileName())) {
86 qCWarning(ComponentInformationCacheLog) <<
"File copy failed from:to" << fileName << data.fileName() << fileToCache.errorString();
89 if (!fileToCache.remove()) {
90 qCWarning(ComponentInformationCacheLog) <<
"File remove failed after copy for" << fileToCache.fileName() << fileToCache.errorString();
96 m.accessCounter = _nextAccessCounter;
97 if (meta.open(QIODevice::WriteOnly)) {
98 if (meta.write((
const char*)&m,
sizeof(m)) !=
sizeof(m)) {
99 qCWarning(ComponentInformationCacheLog) <<
"Meta write failed" << meta.fileName() << meta.errorString();
103 qCWarning(ComponentInformationCacheLog) <<
"Failed to open" << meta.fileName() << meta.errorString();
107 _cachedFiles[_nextAccessCounter++] = fileTag;
111 return data.fileName();
114void ComponentInformationCache::initializeDirectory()
117 qCWarning(ComponentInformationCacheLog) <<
"Failed to create dir" << _path.path();
120 QDir::Filters filters = QDir::Files | QDir::NoDotAndDotDot;
121 QDirIterator it(_path.path(), filters, QDirIterator::NoIteratorFlags);
122 while (it.hasNext()) {
123 QString path = it.next();
125 if (path.endsWith(_metaExtension)) {
127 QFile data(path.mid(0, path.length()-strlen(_metaExtension))+_cacheExtension);
128 bool validationFailed =
false;
129 if (!data.exists()) {
130 validationFailed =
true;
135 const uint32_t expectedMagic = m.magic;
136 const uint32_t expectedVersion = m.version;
137 if (meta.open(QIODevice::ReadOnly)) {
138 if (meta.read((
char*)&m,
sizeof(m)) ==
sizeof(m)) {
139 if (m.magic != expectedMagic || m.version != expectedVersion) {
140 validationFailed =
true;
143 validationFailed =
true;
147 validationFailed =
true;
150 if (validationFailed) {
151 qCWarning(ComponentInformationCacheLog) <<
"Validation failed, removing cache files" << path;
156 QString tag = it.fileName();
157 tag = tag.mid(0, tag.length()-strlen(_metaExtension));
158 _cachedFiles[m.accessCounter] = tag;
160 qCDebug(ComponentInformationCacheLog) <<
"Found cached file:counter" << meta.fileName() << m.accessCounter;
162 if (m.accessCounter >= _nextAccessCounter) {
163 _nextAccessCounter = m.accessCounter + 1;
167 }
else if (!path.endsWith(_cacheExtension)) {
171 _numFiles = _cachedFiles.size();
175void ComponentInformationCache::removeOldEntries()
177 while (_numFiles > _maxNumFiles) {
178 auto iter = _cachedFiles.begin();
179 QFile meta(metaFileName(iter.value()));
180 QFile data(dataFileName(iter.value()));
181 qCDebug(ComponentInformationCacheLog) <<
"Removing cache entry num:counter:file" << _numFiles << iter.key() << iter.value();
185 _cachedFiles.erase(iter);
#define QGC_LOGGING_CATEGORY(name, categoryStr)
bool ensureDirectoryExists(const QString &path)