#include "assemblyDefinitionFileCache.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <cassert>
#include <utility>
namespace {
AssemblyDefinitionFileCache fsTheInstance;
}
AssemblyDefinitionFileCache::Timestamp::Timestamp(
const MString& path)
: fFileSize(-1)
{
struct stat stat_buf;
if (stat(path.
asChar(), &stat_buf) != 0)
return;
fFileSize = stat_buf.st_size;
fMTime = stat_buf.st_mtime;
}
inline bool operator==(const AssemblyDefinitionFileCache::Timestamp& lhs,
const AssemblyDefinitionFileCache::Timestamp& rhs)
{
return (lhs.fFileSize == rhs.fFileSize &&
lhs.fMTime == rhs.fMTime );
}
void AssemblyDefinitionFileCache::Entry::Deleter::operator()(Entry* entry)
{
AssemblyDefinitionFileCache& cache =
AssemblyDefinitionFileCache::getInstance();
Entries::iterator it = cache.fEntries.find(entry->fDefnFile);
if (it != cache.fEntries.end()) {
if (it->second.expired()) {
cache.fEntries.erase(it);
}
}
delete entry;
}
AssemblyDefinitionFileCache& AssemblyDefinitionFileCache::getInstance()
{
return fsTheInstance;
}
AssemblyDefinitionFileCache::EntryPtr
AssemblyDefinitionFileCache::get(
const MString& defnFile)
{
using namespace std::rel_ops;
Entries::iterator it = fEntries.find(std::string(defnFile.
asChar()));
if (it == fEntries.end()) return EntryPtr();
EntryPtr entry(it->second);
if (!entry) return EntryPtr();
const Timestamp timestamp(defnFile);
if (entry->getTimestamp() != timestamp) {
fEntries.erase(it);
return EntryPtr();
}
return entry;
}
AssemblyDefinitionFileCache::EntryPtr
AssemblyDefinitionFileCache::insert(
const RepCreationArgsList& repCreationArgsList)
{
const std::string defnFileString(defnFile.
asChar());
EntryPtr entry(
new Entry(defnFileString,
Timestamp(defnFile),
repCreationArgsList),
Entry::Deleter());
#ifndef NDEBUG
std::pair<Entries::iterator, bool> result =
#endif
fEntries.insert(std::make_pair(defnFileString, entry));
assert(result.second);
return entry;
}