blob: fae2aa54b0688fbcf8b4703517277614a44f067f [file] [log] [blame]
#include "file_cache.h"
#include "tuningfork_utils.h"
#define LOG_TAG "TuningFork"
#include <cinttypes>
#include <sstream>
#include "Log.h"
namespace tf = tuningfork;
namespace {
extern "C" TuningFork_ErrorCode FileCacheGet(
uint64_t key, TuningFork_CProtobufSerialization* value, void* _self) {
if (_self == nullptr) return TUNINGFORK_ERROR_BAD_PARAMETER;
tf::FileCache* self = static_cast<tf::FileCache*>(_self);
return self->Get(key, value);
}
extern "C" TuningFork_ErrorCode FileCacheSet(
uint64_t key, const TuningFork_CProtobufSerialization* value, void* _self) {
if (_self == nullptr) return TUNINGFORK_ERROR_BAD_PARAMETER;
tf::FileCache* self = static_cast<tf::FileCache*>(_self);
return self->Set(key, value);
}
extern "C" TuningFork_ErrorCode FileCacheRemove(uint64_t key, void* _self) {
if (_self == nullptr) return TUNINGFORK_ERROR_BAD_PARAMETER;
tf::FileCache* self = static_cast<tf::FileCache*>(_self);
return self->Remove(key);
}
} // anonymous namespace
namespace tuningfork {
using namespace file_utils;
std::string PathToKey(const std::string& path, uint64_t key) {
std::stringstream str;
str << path << "/local_cache_" << key;
return str.str();
}
FileCache::FileCache(const std::string& path) : path_(path) {
c_cache_ = TuningFork_Cache{(void*)this, &FileCacheSet, &FileCacheGet,
&FileCacheRemove};
}
TuningFork_ErrorCode FileCache::Get(uint64_t key,
TuningFork_CProtobufSerialization* value) {
std::lock_guard<std::mutex> lock(mutex_);
ALOGV("FileCache::Get %" PRIu64, key);
if (CheckAndCreateDir(path_)) {
auto key_path = PathToKey(path_, key);
if (FileExists(key_path)) {
ALOGV("File %s exists", key_path.c_str());
if (LoadBytesFromFile(key_path, value)) {
ALOGV("Loaded key %" PRId64 " from %s (%" PRIu32 " bytes)", key,
key_path.c_str(), value->size);
return TUNINGFORK_ERROR_OK;
}
} else {
ALOGV("File %s does not exist", key_path.c_str());
}
}
return TUNINGFORK_ERROR_NO_SUCH_KEY;
}
TuningFork_ErrorCode FileCache::Set(
uint64_t key, const TuningFork_CProtobufSerialization* value) {
std::lock_guard<std::mutex> lock(mutex_);
ALOGV("FileCache::Set %" PRIu64, key);
if (CheckAndCreateDir(path_)) {
auto key_path = PathToKey(path_, key);
if (SaveBytesToFile(key_path, value)) {
ALOGV("Saved key %" PRId64 " to %s (%" PRIu32 " bytes)", key,
key_path.c_str(), value->size);
return TUNINGFORK_ERROR_OK;
}
}
return TUNINGFORK_ERROR_NO_SUCH_KEY;
}
TuningFork_ErrorCode FileCache::Remove(uint64_t key) {
std::lock_guard<std::mutex> lock(mutex_);
ALOGV("FileCache::Remove %" PRIu64, key);
if (CheckAndCreateDir(path_)) {
auto key_path = PathToKey(path_, key);
if (DeleteFile(key_path)) {
ALOGV("Deleted key %" PRId64 " (%s)", key, key_path.c_str());
return TUNINGFORK_ERROR_OK;
}
}
return TUNINGFORK_ERROR_NO_SUCH_KEY;
}
TuningFork_ErrorCode FileCache::Clear() {
std::lock_guard<std::mutex> lock(mutex_);
ALOGV("FileCache::Clear");
if (DeleteDir(path_))
return TUNINGFORK_ERROR_OK;
else
return TUNINGFORK_ERROR_BAD_FILE_OPERATION;
}
bool FileCache::IsValid() const { return CheckAndCreateDir(path_); }
} // namespace tuningfork