-
Notifications
You must be signed in to change notification settings - Fork 5
/
stream_id.h
92 lines (81 loc) · 3.17 KB
/
stream_id.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#ifndef STREAM_ID_H
#define STREAM_ID_H
#include<sys/socket.h>
#include<netinet/in.h>
#include "homa.h"
#include "src/core/lib/iomgr/resolve_address.h"
/**
* Holds information identifying a stream (which represents a gRPC RPC)
* in a form that can be used as a key in std::unordered_map.
*/
struct StreamId {
// Specifies the address and port of the other machine.
sockaddr_in_union addr;
// Unique id for this RPC among all those from its client.
uint32_t id;
StreamId() {}
StreamId(uint32_t id);
StreamId(const StreamId &other);
StreamId(grpc_resolved_address *gaddr, uint32_t id);
StreamId& operator=(const StreamId &other);
bool operator==(const StreamId& other) const;
std::string toString();
int port()
{
if (addr.in6.sin6_family == AF_INET6) {
return htons(addr.in6.sin6_port);
} else if (addr.in4.sin_family == AF_INET) {
return htons(addr.in4.sin_port);
}
return -1;
}
/**
* This class computes a hash of an StreamId, so that StreamIds can
* be used as keys in unordered_maps.
*/
struct Hasher {
std::size_t operator()(const StreamId& streamId) const
{
std::size_t hash = 0;
if (streamId.addr.in6.sin6_family == AF_INET6) {
hash ^= std::hash<int>()(streamId.addr.in6.sin6_addr.s6_addr32[0]);
hash ^= std::hash<int>()(streamId.addr.in6.sin6_addr.s6_addr32[1]);
hash ^= std::hash<int>()(streamId.addr.in6.sin6_addr.s6_addr32[2]);
hash ^= std::hash<int>()(streamId.addr.in6.sin6_addr.s6_addr32[3]);
hash ^= std::hash<short>()(streamId.addr.in6.sin6_port);
} else if (streamId.addr.in4.sin_family == AF_INET) {
hash ^= std::hash<int>()(streamId.addr.in4.sin_addr.s_addr);
hash ^= std::hash<short>()(streamId.addr.in4.sin_port);
}
return hash ^ streamId.id;
}
};
struct Pred {
bool operator()(const StreamId& a, const StreamId& b) const
{
if (a.id != b.id) {
return false;
}
if (a.addr.in6.sin6_family != b.addr.in6.sin6_family) {
return false;
}
if (a.addr.in6.sin6_family == AF_INET6) {
return (a.addr.in6.sin6_addr.s6_addr32[0]
== b.addr.in6.sin6_addr.s6_addr32[0])
&& (a.addr.in6.sin6_addr.s6_addr32[1]
== b.addr.in6.sin6_addr.s6_addr32[1])
&& (a.addr.in6.sin6_addr.s6_addr32[2]
== b.addr.in6.sin6_addr.s6_addr32[2])
&& (a.addr.in6.sin6_addr.s6_addr32[3]
== b.addr.in6.sin6_addr.s6_addr32[3])
&& (a.addr.in6.sin6_port == b.addr.in6.sin6_port);
} else if (a.addr.in4.sin_family == AF_INET) {
return (a.addr.in4.sin_addr.s_addr
== b.addr.in4.sin_addr.s_addr)
&& (a.addr.in4.sin_port == b.addr.in4.sin_port);
}
return false;
}
};
};
#endif // STREAM_ID_H