//------------------------------------------------------------------------------
// File: Members.hh
// Author: Georgios Bitzes - CERN
//------------------------------------------------------------------------------
/************************************************************************
* qclient - A simple redis C++ client with support for redirects *
* Copyright (C) 2016 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see .*
************************************************************************/
#ifndef QCLIENT_MEMBERS_H
#define QCLIENT_MEMBERS_H
#include
#include
#include
#include
namespace qclient {
class Endpoint {
public:
Endpoint(const std::string &host_, int port_) : host(host_), port(port_) {}
Endpoint() {}
const std::string& getHost() const {
return host;
}
int getPort() const {
return port;
}
bool empty() const {
return host.empty() || port <= 0;
}
std::string toString() const {
std::stringstream ss;
ss << host << ":" << port;
return ss.str();
}
bool operator==(const Endpoint &other) const {
return host == other.host && port == other.port;
}
bool operator<(const Endpoint &other) const {
if(host != other.host) {
return host < other.host;
}
return port < other.port;
}
private:
std::string host;
int port = -1;
};
class Members {
public:
Members() {}
Members(const std::string &host, int port) {
members.emplace_back(host, port);
}
Members(const std::vector &members_) : members(members_) {}
void clear() {
members.clear();
}
const std::vector& getEndpoints() const {
return members;
}
void push_back(const std::string &host, int port) {
members.emplace_back(host, port);
}
void push_back(const Endpoint& endpoint) {
members.push_back(endpoint);
}
size_t size() const {
return members.size();
}
bool empty() const {
return members.empty();
}
static Members fromString(const std::string &input) {
Members ret;
ret.parse(input);
return ret;
}
bool parse(const std::string& input) {
bool valid = false;
std::istringstream iss(input);
std::string token;
while (std::getline(iss, token, ' ')) {
size_t pos = token.find(':');
if (pos != std::string::npos) {
try {
size_t conv_pos = 0;
std::string host = token.substr(0, pos);
uint32_t port = std::stoul(token.substr(pos + 1), &conv_pos);
if (conv_pos == (token.length() - pos - 1)) {
members.emplace_back(host, port);
valid = true;
}
} catch (const std::exception& e) {
continue;
}
}
}
return valid;
}
std::string toString() const {
std::ostringstream ss;
for(size_t i = 0; i < members.size(); i++) {
ss << members[i].getHost() << ":" << members[i].getPort();
if(i != members.size() - 1) {
ss << ",";
}
}
return ss.str();
}
bool operator<(const Members& other) const {
if(members.size() != other.members.size()) {
return members.size() < other.members.size();
}
for(size_t i = 0; i < other.size(); i++) {
if(!(members[i] == other.members[i])) {
return members[i] < other.members[i];
}
}
return false; // the two are equal
}
private:
std::vector members;
};
}
#endif