optimized IPaddress
This commit is contained in:
parent
9e8237955f
commit
e5a80f2c94
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue