Skip to content

Commit

Permalink
Implement initial reinit logic (#3)
Browse files Browse the repository at this point in the history
* Implement initial reinit logic and update logging

* Fix sairedis logging

* Use other db connection for notifications

* Syncd get log level from redis

* Build dummy port map

* Add RedisClient class

* Fix serialize bug for route and neighbor
  • Loading branch information
kcudnik authored and lguohan committed Apr 14, 2016
1 parent 8177924 commit a6f1770
Show file tree
Hide file tree
Showing 47 changed files with 2,694 additions and 877 deletions.
262 changes: 262 additions & 0 deletions common/redisclient.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
#include "redisclient.h"

namespace swss
{

RedisClient::RedisClient(swss::DBConnector *db):
m_db(db)
{
}

int64_t RedisClient::del(std::string key)
{
char *temp;
int len = redisFormatCommand(&temp, "DEL %s", key.c_str());
std::string del(temp, len);
free(temp);

RedisReply r(m_db, del, REDIS_REPLY_INTEGER, true);

if (r.getContext()->type != REDIS_REPLY_INTEGER)
throw std::runtime_error("DEL operation failed");

return r.getContext()->integer;
}

int64_t RedisClient::hdel(std::string key, std::string field)
{
char *temp;
int len = redisFormatCommand(&temp, "HDEL %s %s", key.c_str(), field.c_str());
std::string hdel(temp, len);
free(temp);

RedisReply r(m_db, hdel, REDIS_REPLY_INTEGER, true);

if (r.getContext()->type != REDIS_REPLY_INTEGER)
throw std::runtime_error("HDEL operation failed");

return r.getContext()->integer;
}

void RedisClient::hset(std::string key, std::string field, std::string value)
{
char *temp;
int len = redisFormatCommand(&temp, "HSET %s %s %s", key.c_str(), field.c_str(), value.c_str());
std::string hset(temp, len);
free(temp);

RedisReply r(m_db, hset, REDIS_REPLY_INTEGER, true);

if (r.getContext()->type != REDIS_REPLY_INTEGER)
throw std::runtime_error("HSET operation failed");
}

void RedisClient::set(std::string key, std::string value)
{
char *temp;
int len = redisFormatCommand(&temp, "SET %s %s", key.c_str(), value.c_str());
std::string set(temp, len);
free(temp);

RedisReply r(m_db, set, REDIS_REPLY_STATUS, true);

if (r.getContext()->type != REDIS_REPLY_STATUS)
throw std::runtime_error("SET operation failed");
}

std::unordered_map<std::string, std::string> RedisClient::hgetall(std::string key)
{
std::unordered_map<std::string, std::string> map;

char *temp;
int len = redisFormatCommand(&temp, "HGETALL %s", key.c_str());

std::string incr(temp, len);
free(temp);

RedisReply r(m_db, incr, REDIS_REPLY_ARRAY, true);

if (r.getContext()->type != REDIS_REPLY_ARRAY)
throw std::runtime_error("HGETALL operation failed");

auto ctx = r.getContext();

for (unsigned int i = 0; i < ctx->elements; i += 2)
map[std::string(ctx->element[i]->str)] = std::string(ctx->element[i+1]->str);

return map;
}

std::vector<std::string> RedisClient::keys(std::string key)
{
std::vector<std::string> list;

char *temp;
int len = redisFormatCommand(&temp, "KEYS %s", key.c_str());

std::string keys(temp, len);
free(temp);

RedisReply r(m_db, keys, REDIS_REPLY_ARRAY, true);

if (r.getContext()->type != REDIS_REPLY_ARRAY)
throw std::runtime_error("KEYS operation failed");

auto ctx = r.getContext();

for (unsigned int i = 0; i < ctx->elements; i++)
list.push_back(ctx->element[i]->str);

return list;
}

int64_t RedisClient::incr(std::string key)
{
char *temp;
int len = redisFormatCommand(&temp, "INCR %s", key.c_str());

std::string incr(temp, len);
free(temp);

RedisReply r(m_db, incr, REDIS_REPLY_INTEGER, true);

if (r.getContext()->type != REDIS_REPLY_INTEGER)
throw std::runtime_error("INCR command failed");

return r.getContext()->integer;
}

int64_t RedisClient::decr(std::string key)
{
char *temp;
int len = redisFormatCommand(&temp, "DECR %s", key.c_str());

std::string decr(temp, len);
free(temp);

RedisReply r(m_db, decr, REDIS_REPLY_INTEGER, true);

if (r.getContext()->type != REDIS_REPLY_INTEGER)
throw std::runtime_error("DECR command failed");

return r.getContext()->integer;
}

std::shared_ptr<std::string> RedisClient::get(std::string key)
{
char *temp;
int len = redisFormatCommand(&temp, "GET %s", key.c_str());

std::string get(temp, len);
free(temp);

redisReply *reply;

redisAppendFormattedCommand(m_db->getContext(), get.c_str(), get.length());
redisGetReply(m_db->getContext(), (void**)&reply);

if (!reply)
throw std::runtime_error("GET failed, memory exception");

if (reply->type == REDIS_REPLY_NIL)
{
freeReplyObject(reply);
return std::shared_ptr<std::string>(NULL);
}

if (reply->type == REDIS_REPLY_STRING)
{
std::shared_ptr<std::string> ptr(new std::string(reply->str));
freeReplyObject(reply);
return ptr;
}

freeReplyObject(reply);

throw std::runtime_error("GET failed, memory exception");
}

std::shared_ptr<std::string> RedisClient::hget(std::string key, std::string field)
{
char *temp;
int len = redisFormatCommand(&temp, "HGET %s %s", key.c_str(), field.c_str());

std::string hget(temp, len);
free(temp);

redisReply *reply;

redisAppendFormattedCommand(m_db->getContext(), hget.c_str(), hget.length());
redisGetReply(m_db->getContext(), (void**)&reply);

if (!reply)
throw std::runtime_error("HGET failed, memory exception");

if (reply->type == REDIS_REPLY_NIL)
{
freeReplyObject(reply);
return std::shared_ptr<std::string>(NULL);
}

if (reply->type == REDIS_REPLY_STRING)
{
std::shared_ptr<std::string> ptr(new std::string(reply->str));
freeReplyObject(reply);
return ptr;
}

freeReplyObject(reply);

throw std::runtime_error("HGET failed, memory exception");
}

int64_t RedisClient::rpush(std::string list, std::string item)
{
char *temp;
int len = redisFormatCommand(&temp, "RPUSH %s %s", list.c_str(), item.c_str());

std::string rpush(temp, len);
free(temp);

RedisReply r(m_db, rpush, REDIS_REPLY_INTEGER, true);

if (r.getContext()->type != REDIS_REPLY_INTEGER)
throw std::runtime_error("RPUSH command failed");

return r.getContext()->integer;
}

std::shared_ptr<std::string> RedisClient::blpop(std::string list, int timeout)
{
char *temp;
int len = redisFormatCommand(&temp, "BLPOP %s %d", list.c_str(), timeout);

std::string blpop(temp, len);
free(temp);

redisReply *reply;

redisAppendFormattedCommand(m_db->getContext(), blpop.c_str(), blpop.length());
redisGetReply(m_db->getContext(), (void**)&reply);

if (!reply)
throw std::runtime_error("BLPOP failed, memory exception");

if (reply->type == REDIS_REPLY_NIL)
{
freeReplyObject(reply);
return std::shared_ptr<std::string>(NULL);
}

if (reply->type == REDIS_REPLY_STRING)
{
std::shared_ptr<std::string> ptr(new std::string(reply->str));
freeReplyObject(reply);
return ptr;
}

freeReplyObject(reply);

throw std::runtime_error("GET failed, memory exception");
}
}
67 changes: 67 additions & 0 deletions common/redisclient.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#ifndef __REDISCLIENT_H__
#define __REDISCLIENT_H__

#include <iostream>
#include <string>
#include <vector>
#include <ios>
#include <map>
#include <unordered_map>
#include <sstream>
#include <stdexcept>
#include <system_error>
#include <memory>

#include "swss/dbconnector.h"
#include "swss/redisreply.h"

namespace swss
{

class RedisClient
{
public:

RedisClient(swss::DBConnector *db);

int64_t del(std::string key);

int64_t hdel(std::string key, std::string field);

std::unordered_map<std::string, std::string> hgetall(std::string key);

std::vector<std::string> keys(std::string key);

std::vector<std::string> hkeys(std::string key);

void set(std::string key, std::string value);

void hset(std::string key, std::string field, std::string value);

void mset(std::unordered_map<std::string, std::string> map);

void hmset(std::string key, std::unordered_map<std::string, std::string> map);

std::shared_ptr<std::string> get(std::string key);

std::shared_ptr<std::string> hget(std::string key, std::string field);

std::vector<std::shared_ptr<std::string>> mget(std::vector<std::string> keys);

std::vector<std::shared_ptr<std::string>> hmget(std::string key, std::vector<std::string> fields);

int64_t incr(std::string key);

int64_t decr(std::string key);

int64_t rpush(std::string list, std::string item);

std::shared_ptr<std::string> blpop(std::string list, int timeout);

private:
swss::DBConnector *m_db;
};

}

#endif // __REDISCLIENT_H__
5 changes: 4 additions & 1 deletion common/saiattributelist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ SaiAttributeList::SaiAttributeList(
const std::string &str_attr_id = fvField(values[i]);
const std::string &str_attr_value = fvValue(values[i]);

if (str_attr_id == "NULL")
continue;

sai_attribute_t attr;
memset(&attr, 1, sizeof(sai_attribute_t));
memset(&attr, 0, sizeof(sai_attribute_t));

int index = 0;
sai_deserialize_primitive(str_attr_id, index, attr.id);
Expand Down
1 change: 1 addition & 0 deletions common/saiattributelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <hiredis/hiredis.h>
#include "swss/dbconnector.h"
#include "swss/table.h"
#include "swss/logger.h"
#include "sai.h"
#include "saiserialize.h"
#include "string.h"
Expand Down
Loading

0 comments on commit a6f1770

Please sign in to comment.