@@ -31,35 +31,73 @@ class ConnectionPoolImpl
31
31
public:
32
32
33
33
struct Key {
34
- Key (boost::asio::ip::tcp::endpoint ep,
35
- const Connection::Type connectionType)
36
- : endpoint{std::move (ep)}, type{connectionType} {}
34
+ Key (boost::asio::ip::tcp::endpoint ep, Connection::Type connectionType)
35
+ : endpoint(std::move(ep)), type(connectionType) {}
37
36
38
37
Key (const Key&) = default ;
39
38
Key (Key&&) = default ;
40
39
~Key () = default ;
41
- Key& operator = (const Key&) = delete ;
42
- Key& operator = (Key&&) = delete ;
40
+ Key& operator = (const Key&) = delete ;
41
+ Key& operator = (Key&&) = delete ;
43
42
44
- bool operator < (const Key& key) const {
43
+ bool operator < (const Key& key) const {
45
44
if (static_cast <int >(type) < static_cast <int >(key.type )) {
46
45
return true ;
47
46
}
48
-
47
+ if (static_cast <int >(type) > static_cast <int >(key.type )) {
48
+ return false ;
49
+ }
49
50
return endpoint < key.endpoint ;
50
51
}
51
52
52
- friend std::ostream& operator << (std::ostream& o, const Key& v) {
53
+ bool operator ==(const Key& key) const {
54
+ return type == key.type && endpoint == key.endpoint ;
55
+ }
56
+
57
+ friend std::ostream& operator <<(std::ostream& o, const Key& v) {
53
58
return o << " {Key "
54
- << (v.type == Connection::Type::HTTPS? " https" : " http" )
55
- << " ://"
56
- << v.endpoint
57
- << " }" ;
59
+ << (v.type == Connection::Type::HTTPS ? " https" : " http" )
60
+ << " ://"
61
+ << v.endpoint
62
+ << " }" ;
58
63
}
59
64
65
+ // Custom hash function
66
+ struct KeyHash {
67
+ std::size_t operator ()(const Key& key) const {
68
+ std::size_t h1 = 0 ;
69
+
70
+ // Hash the binary address data
71
+ if (key.endpoint .address ().is_v4 ()) {
72
+ // IPv4: 4 bytes
73
+ const auto addr = key.endpoint .address ().to_v4 ().to_bytes ();
74
+ h1 = std::hash<uint32_t >()(*reinterpret_cast <const uint32_t *>(addr.data ()));
75
+ } else if (key.endpoint .address ().is_v6 ()) {
76
+ // IPv6: 16 bytes
77
+ const auto addr = key.endpoint .address ().to_v6 ().to_bytes ();
78
+ const uint64_t * parts = reinterpret_cast <const uint64_t *>(addr.data ());
79
+ h1 = std::hash<uint64_t >()(parts[0 ]) ^ std::hash<uint64_t >()(parts[1 ]);
80
+ }
81
+
82
+ // Hash the port and type
83
+ std::size_t h2 = std::hash<unsigned short >()(key.endpoint .port ());
84
+ std::size_t h3 = std::hash<int >()(static_cast <int >(key.type ));
85
+
86
+ // Combine the hashes
87
+ return h1 ^ (h2 << 1 ) ^ (h3 << 2 );
88
+ }
89
+ };
90
+
91
+ // Equality comparison for hash table
92
+ struct KeyEqual {
93
+ bool operator ()(const Key& lhs, const Key& rhs) const {
94
+ return lhs == rhs;
95
+ }
96
+ };
97
+
60
98
private:
61
- const boost::asio::ip::tcp::endpoint endpoint;
62
- const Connection::Type type;
99
+ boost::asio::ip::tcp::endpoint endpoint;
100
+ Connection::Type type;
63
101
};
64
102
65
103
struct Entry {
@@ -400,8 +438,8 @@ class ConnectionPoolImpl
400
438
#endif
401
439
std::once_flag close_once_;
402
440
RestClient& owner_;
403
- multimap <Key, Entry::ptr_t > idle_;
404
- multimap <Key, std::weak_ptr<Entry>> in_use_;
441
+ unordered_multimap <Key, Entry::ptr_t , Key::KeyHash, Key::KeyEqual > idle_;
442
+ unordered_multimap <Key, std::weak_ptr<Entry>, Key::KeyHash, Key::KeyEqual > in_use_;
405
443
// std::queue<Entry> pending_;
406
444
const Request::Properties::ptr_t properties_;
407
445
ConnectionWrapper::release_callback_t on_release_;
0 commit comments