optimized IPaddress

This commit is contained in:
Evan Tschannen 2019-03-27 18:21:13 -07:00
parent 9e8237955f
commit e5a80f2c94
4 changed files with 76 additions and 52 deletions

View File

@ -28,6 +28,7 @@
#include "fdbrpc/FailureMonitor.h"
#include "fdbrpc/crc32c.h"
#include "fdbrpc/simulator.h"
#include <unordered_map>
#if VALGRIND
#include <memcheck.h>
@ -168,7 +169,7 @@ public:
NetworkAddressList localAddresses;
std::vector<Future<Void>> listeners;
std::map<NetworkAddress, struct Peer*> peers;
std::unordered_map<NetworkAddress, struct Peer*> peers;
bool warnAlwaysForLargePacket;
// These declarations must be in exactly this order

View File

@ -1244,24 +1244,6 @@ ACTOR static Future<JsonBuilderObject> dataStatusFetcher(WorkerDetails ddWorker,
return statusObjData;
}
namespace std
{
template <>
struct hash<NetworkAddress>
{
size_t operator()(const NetworkAddress& na) const
{
int result = 0;
if (na.ip.isV6()) {
result = hashlittle(na.ip.toV6().data(), 16, 0);
} else {
result = na.ip.toV4();
}
return (result << 16) + na.port;
}
};
}
ACTOR template <class iface>
static Future<vector<std::pair<iface, EventMap>>> getServerMetrics(vector<iface> servers, std::unordered_map<NetworkAddress, WorkerInterface> address_workers, std::vector<std::string> eventNames) {
state vector<Future<Optional<TraceEventFields>>> futures;

View File

@ -24,38 +24,41 @@
#include "flow/flow.h"
#include "flow/UnitTest.h"
IPAddress::IPAddress() : store({}), isV6addr(false) {}
IPAddress::IPAddress(const IPAddressStore& v6addr) : store(v6addr), isV6addr(true) {}
IPAddress::IPAddress(uint32_t v4addr) : store({}), isV6addr(false) {
uint32_t* parts = (uint32_t*)store.data();
parts[0] = v4addr;
IPAddress::IPAddress() : isV4addr(true) {
addr.v4 = 0;
}
uint32_t IPAddress::toV4() const {
const uint32_t* parts = (uint32_t*)store.data();
return parts[0];
IPAddress::IPAddress(const IPAddressStore& v6addr) : isV4addr(false) {
addr.v6 = v6addr;
}
bool IPAddress::operator==(const IPAddress& addr) const {
return isV6addr == addr.isV6addr && store == addr.store;
IPAddress::IPAddress(uint32_t v4addr) : isV4addr(true) {
addr.v4 = v4addr;
}
bool IPAddress::operator==(const IPAddress& rhs) const {
return isV4addr == rhs.isV4addr && (isV4addr ? addr.v4 == rhs.addr.v4 : addr.v6 == rhs.addr.v6);
}
bool IPAddress::operator!=(const IPAddress& addr) const {
return !(*this == addr);
}
bool IPAddress::operator<(const IPAddress& addr) const {
return isV6() == addr.isV6() ? store < addr.store : isV6() < addr.isV6();
bool IPAddress::operator<(const IPAddress& rhs) const {
if(isV4addr != rhs.isV4addr) {
return isV4addr < rhs.isV4addr;
}
if(isV4addr) {
return addr.v4 < rhs.addr.v4;
}
return addr.v6 < rhs.addr.v6;
}
std::string IPAddress::toString() const {
if (isV6()) {
return boost::asio::ip::address_v6(store).to_string();
if (isV4addr) {
return format("%d.%d.%d.%d", (addr.v4 >> 24) & 0xff, (addr.v4 >> 16) & 0xff, (addr.v4 >> 8) & 0xff, addr.v4 & 0xff);
} else {
const uint32_t ip = toV4();
return format("%d.%d.%d.%d", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
return boost::asio::ip::address_v6(addr.v6).to_string();
}
}
@ -69,11 +72,10 @@ Optional<IPAddress> IPAddress::parse(std::string str) {
}
bool IPAddress::isValid() const {
if (!isV6()) {
return toV4() != 0;
if (isV4addr) {
return addr.v4 != 0;
}
return std::any_of(store.begin(), store.end(), [](uint8_t part) { return part > 0; });
return std::any_of(addr.v6.begin(), addr.v6.end(), [](uint8_t part) { return part != 0; });
}
NetworkAddress NetworkAddress::parse( std::string const& s ) {

View File

@ -28,6 +28,7 @@
#include "boost/asio.hpp"
#include "flow/serialize.h"
#include "flow/IRandom.h"
#include "fdbrpc/crc32c.h"
enum {
TaskMaxPriority = 1000000,
@ -91,14 +92,32 @@ struct IPAddress {
explicit IPAddress(const IPAddressStore& v6addr);
explicit IPAddress(uint32_t v4addr);
bool isV6() const { return isV6addr; }
bool isV4() const { return !isV6addr; }
bool isV6() const { return !isV4addr; }
bool isV4() const { return isV4addr; }
bool isValid() const;
IPAddress(const IPAddress& rhs) : isV4addr(rhs.isV4addr) {
if(isV4addr) {
addr.v4 = rhs.addr.v4;
} else {
addr.v6 = rhs.addr.v6;
}
}
IPAddress& operator=(const IPAddress& rhs) {
isV4addr = rhs.isV4addr;
if(isV4addr) {
addr.v4 = rhs.addr.v4;
} else {
addr.v6 = rhs.addr.v6;
}
return *this;
}
// Returns raw v4/v6 representation of address. Caller is responsible
// to call these functions safely.
uint32_t toV4() const;
const IPAddressStore& toV6() const { return store; }
uint32_t toV4() const { return addr.v4; }
const IPAddressStore& toV6() const { return addr.v6; }
std::string toString() const;
static Optional<IPAddress> parse(std::string str);
@ -109,18 +128,20 @@ struct IPAddress {
template <class Ar>
void serialize(Ar& ar) {
serializer(ar, isV6addr);
if (isV6addr) {
serializer(ar, store);
serializer(ar, isV4addr);
if(isV4addr) {
serializer(ar, addr.v4);
} else {
uint32_t* parts = (uint32_t*)store.data();
serializer(ar, parts[0]);
serializer(ar, addr.v6);
}
}
private:
bool isV6addr;
IPAddressStore store;
bool isV4addr;
union {
uint32_t v4;
IPAddressStore v6;
} addr;
};
struct NetworkAddress {
@ -171,6 +192,24 @@ struct NetworkAddress {
}
};
namespace std
{
template <>
struct hash<NetworkAddress>
{
size_t operator()(const NetworkAddress& na) const
{
int result = 0;
if (na.ip.isV6()) {
result = crc32c_append( 0xfdbeefdb, (uint8_t*)na.ip.toV6().data(), 16 );
} else {
result = na.ip.toV4();
}
return (result << 16) + na.port;
}
};
}
struct NetworkAddressList {
NetworkAddress address;
Optional<NetworkAddress> secondaryAddress;