Skip to content

Commit

Permalink
Add support for checking cache incompatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
pranavk committed Apr 22, 2019
1 parent be0e00a commit 39435b8
Showing 1 changed file with 55 additions and 1 deletion.
56 changes: 55 additions & 1 deletion lib/KVStore/KVStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include "llvm/Support/CommandLine.h"
#include "hiredis.h"

#include <sstream>

using namespace llvm;
using namespace souper;

Expand All @@ -26,7 +28,12 @@ static cl::opt<unsigned> RedisPort("souper-redis-port", cl::init(6379),
namespace souper {

class KVStore::KVImpl {
redisContext *Ctx;
redisContext *Ctx = 0;

private:
// checks if current redis database is compatible with current version of souper
bool checkCompatibility();

public:
KVImpl();
~KVImpl();
Expand All @@ -46,12 +53,59 @@ KVStore::KVImpl::KVImpl() {
llvm::report_fatal_error((llvm::StringRef)"Redis connection error: " +
Ctx->errstr + "\n");
}

if (!checkCompatibility()) {
llvm::report_fatal_error("Redis database on port %d is incompatible.", RedisPort);
}
}

KVStore::KVImpl::~KVImpl() {
redisFree(Ctx);
}

bool KVStore::KVImpl::checkCompatibility() {
assert(Ctx && "Cannot check compatibility on an uninitialized database.");

redisReply *reply = static_cast<redisReply*>(redisCommand(Ctx, "GET cachetype"));
if (!reply || Ctx->err) {
llvm::report_fatal_error((llvm::StringRef)"Redis error: " + Ctx->errstr);
}

// get all current command line used
StringMap<cl::Option*> &Opts = cl::getRegisteredOptions();
std::vector<std::string> ActiveOptions;
for (auto &K : Opts.keys()) {
if (Opts[K]->getNumOccurrences() && K.find("-debug-level") == StringRef::npos) {
ActiveOptions.emplace_back(K.str());
}
}
std::sort(ActiveOptions.begin(), ActiveOptions.end());
std::ostringstream ActiveOptionsOSS;
const char *delim = ",";
std::copy(ActiveOptions.begin(), ActiveOptions.end(),
std::ostream_iterator<std::string>(ActiveOptionsOSS, delim));
std::string ActiveOptionsStr = ActiveOptionsOSS.str();

switch(reply->type) {
case REDIS_REPLY_NIL:
// no version set
freeReplyObject(reply);
reply = static_cast<redisReply*>(redisCommand(Ctx, "SET cachetype %s", ActiveOptionsStr.data()));
// TODO: Factor out all such snippets
if (!reply || Ctx->err) {
llvm::report_fatal_error((llvm::StringRef)"Redis error: " + Ctx->errstr);
}
break;
case REDIS_REPLY_STRING:
if (llvm::StringRef value = reply->str; value != ActiveOptionsStr)
return false;
break;
default: return false;
}

return true;
}

void KVStore::KVImpl::hIncrBy(llvm::StringRef Key, llvm::StringRef Field,
int Incr) {
redisReply *reply = (redisReply *)redisCommand(Ctx, "HINCRBY %s %s 1",
Expand Down

0 comments on commit 39435b8

Please sign in to comment.