libDwm-0.9.45
DwmIpv6AddrMap.hh
Go to the documentation of this file.
1//===========================================================================
2// @(#) $DwmPath$
3//===========================================================================
4// Copyright (c) Daniel W. McRobb 2021, 2023, 2024
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions
9// are met:
10//
11// 1. Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// 2. Redistributions in binary form must reproduce the above copyright
14// notice, this list of conditions and the following disclaimer in the
15// documentation and/or other materials provided with the distribution.
16// 3. The names of the authors and copyright holders may not be used to
17// endorse or promote products derived from this software without
18// specific prior written permission.
19//
20// IN NO EVENT SHALL DANIEL W. MCROBB BE LIABLE TO ANY PARTY FOR
21// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
22// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE,
23// EVEN IF DANIEL W. MCROBB HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
24// DAMAGE.
25//
26// THE SOFTWARE PROVIDED HEREIN IS ON AN "AS IS" BASIS, AND
27// DANIEL W. MCROBB HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
28// UPDATES, ENHANCEMENTS, OR MODIFICATIONS. DANIEL W. MCROBB MAKES NO
29// REPRESENTATIONS AND EXTENDS NO WARRANTIES OF ANY KIND, EITHER
30// IMPLIED OR EXPRESS, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31// WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,
32// OR THAT THE USE OF THIS SOFTWARE WILL NOT INFRINGE ANY PATENT,
33// TRADEMARK OR OTHER RIGHTS.
34//===========================================================================
35
36//---------------------------------------------------------------------------
40//---------------------------------------------------------------------------
41
42#ifndef _DWMIPV6ADDRMAP_HH_
43#define _DWMIPV6ADDRMAP_HH_
44
45#include <mutex>
46#include <shared_mutex>
47#include <unordered_map>
48
49#include "DwmASIO.hh"
50#include "DwmBZ2IO.hh"
51#include "DwmDescriptorIO.hh"
52#include "DwmFileIO.hh"
53#include "DwmGZIO.hh"
54#include "DwmIOUtils.hh"
55#include "DwmIpv6Address.hh"
56#include "DwmStreamIO.hh"
57
58namespace Dwm {
59
60 //--------------------------------------------------------------------------
62 //--------------------------------------------------------------------------
63 struct OurIpv6AddressHash
64 {
65 inline size_t operator () (const Dwm::Ipv6Address & addr) const
66 {
67 return addr.Hash();
68 }
69 };
70
71 //--------------------------------------------------------------------------
74 //--------------------------------------------------------------------------
75 template <typename T, typename Hash = OurIpv6AddressHash>
77 {
78 public:
79 //------------------------------------------------------------------------
81 //------------------------------------------------------------------------
83 : _mtx(), _map()
84 {
85 _map.max_load_factor(0.25);
86 }
87
88 //------------------------------------------------------------------------
90 //------------------------------------------------------------------------
91 void Add(const Ipv6Address & addr, const T & value)
92 {
93 std::unique_lock lck(_mtx);
94 _map[addr] = value;
95 return;
96 }
97
98 //------------------------------------------------------------------------
100 //------------------------------------------------------------------------
101 void Add(std::unique_lock<std::shared_mutex> & lck,
102 const Ipv6Address & addr, const T & value)
103 {
104 assert((lck.mutex() == &_mtx) && lck.owns_lock());
105 _map[addr] = value;
106 return;
107 }
108
109 //------------------------------------------------------------------------
111 //------------------------------------------------------------------------
112 bool Find(const Ipv6Address & addr, T & value) const
113 {
114 std::shared_lock lck(_mtx);
115 return Find(lck, addr, value);
116 }
117
118 //------------------------------------------------------------------------
120 //------------------------------------------------------------------------
121 bool Find(std::shared_lock<std::shared_mutex> & lck,
122 const Ipv6Address & addr, T & value) const
123 {
124 assert((lck.mutex() == &_mtx) && lck.owns_lock());
125 return FindNoLock(addr, value);
126 }
127
128 //------------------------------------------------------------------------
130 //------------------------------------------------------------------------
131 bool Find(std::unique_lock<std::shared_mutex> & lck,
132 const Ipv6Address & addr, T & value) const
133 {
134 assert((lck.mutex() == &_mtx) && lck.owns_lock());
135 return FindNoLock(addr, value);
136 }
137
138 //------------------------------------------------------------------------
140 //------------------------------------------------------------------------
141 bool Remove(const Ipv6Address & addr)
142 {
143 std::unique_lock lck(_mtx);
144 return Remove(lck, addr);
145 }
146
147 //------------------------------------------------------------------------
149 //------------------------------------------------------------------------
150 bool Remove(std::unique_lock<std::shared_mutex> & lck,
151 const Ipv6Address & addr)
152 {
153 bool rc = false;
154 assert((lck.mutex() == &_mtx) && lck.owns_lock());
155 auto it = _map.find(addr);
156 if (it != _map.end()) {
157 _map.erase(it);
158 rc = true;
159 }
160 return rc;
161 }
162
163 //------------------------------------------------------------------------
165 //------------------------------------------------------------------------
166 bool Empty() const
167 {
168 std::shared_lock lck(_mtx);
169 return Empty(lck);
170 }
171
172 //------------------------------------------------------------------------
174 //------------------------------------------------------------------------
175 bool Empty(std::shared_lock<std::shared_mutex> & lck) const
176 {
177 assert((lck.mutex() == &_mtx) && lck.owns_lock());
178 return _map.empty();
179 }
180
181 //------------------------------------------------------------------------
183 //------------------------------------------------------------------------
184 bool Empty(std::unique_lock<std::shared_mutex> & lck) const
185 {
186 assert((lck.mutex() == &_mtx) && lck.owns_lock());
187 return _map.empty();
188 }
189
190 //------------------------------------------------------------------------
192 //------------------------------------------------------------------------
193 void Clear()
194 {
195 std::unique_lock lck(_mtx);
196 return Clear(lck);
197 }
198
199 //------------------------------------------------------------------------
201 //------------------------------------------------------------------------
202 void Clear(std::unique_lock<std::shared_mutex> & lck)
203 {
204 assert((lck.mutex() == &_mtx) && lck.owns_lock());
205 _map.clear();
206 return;
207 }
208
209 //------------------------------------------------------------------------
211 //------------------------------------------------------------------------
212 std::istream & Read(std::istream & is)
213 {
214 std::unique_lock lck(_mtx);
215 return StreamIO::Read(is, _map);
216 }
217
218 //------------------------------------------------------------------------
220 //------------------------------------------------------------------------
221 std::ostream & Write(std::ostream & os) const
222 {
223 std::shared_lock lck(_mtx);
224 return StreamIO::Write(os, _map);
225 }
226
227 //------------------------------------------------------------------------
230 //------------------------------------------------------------------------
231 size_t Read(FILE *f)
232 {
233 std::unique_lock lck(_mtx);
234 return FileIO::Read(f, _map);
235 }
236
237 //------------------------------------------------------------------------
240 //------------------------------------------------------------------------
241 size_t Write(FILE *f) const
242 {
243 std::shared_lock lck(_mtx);
244 return FileIO::Write(f, _map);
245 }
246
247 //------------------------------------------------------------------------
250 //------------------------------------------------------------------------
251 ssize_t Read(int fd)
252 {
253 std::unique_lock lck(_mtx);
254 return DescriptorIO::Read(fd, _map);
255 }
256
257 //------------------------------------------------------------------------
260 //------------------------------------------------------------------------
261 ssize_t Write(int fd) const
262 {
263 std::shared_lock lck(_mtx);
264 return DescriptorIO::Write(fd, _map);
265 }
266
267 //------------------------------------------------------------------------
272 //------------------------------------------------------------------------
273 int Read(gzFile gzf)
274 {
275 std::unique_lock lck(_mtx);
276 return GZIO::Read(gzf, _map);
277 }
278
279 //------------------------------------------------------------------------
284 //------------------------------------------------------------------------
285 int Write(gzFile gzf) const
286 {
287 std::shared_lock lck(_mtx);
288 return GZIO::Write(gzf, _map);
289 }
290
291 //------------------------------------------------------------------------
296 //------------------------------------------------------------------------
297 int BZRead(BZFILE *bzf)
298 {
299 std::unique_lock lck(_mtx);
300 return BZ2IO::BZRead(bzf, _map);
301 }
302
303 //------------------------------------------------------------------------
308 //------------------------------------------------------------------------
309 int BZWrite(BZFILE *bzf) const
310 {
311 std::shared_lock lck(_mtx);
312 return BZ2IO::BZWrite(bzf, _map);
313 }
314
315 //------------------------------------------------------------------------
318 //------------------------------------------------------------------------
319 uint64_t StreamedLength() const
320 {
321 std::shared_lock lck(_mtx);
322 return IOUtils::StreamedLength(_map);
323 }
324
325 //------------------------------------------------------------------------
328 //------------------------------------------------------------------------
329 bool Read(boost::asio::ip::tcp::socket & s,
330 boost::system::error_code & ec)
331 {
332 std::unique_lock lck(_mtx);
333 return ASIO::Read(s, _map, ec);
334 }
335
336 //------------------------------------------------------------------------
339 //------------------------------------------------------------------------
340 bool Write(boost::asio::ip::tcp::socket & s,
341 boost::system::error_code & ec) const
342 {
343 std::shared_lock lck(_mtx);
344 return ASIO::Write(s, _map, ec);
345 }
346
347 //------------------------------------------------------------------------
350 //------------------------------------------------------------------------
351 bool Read(boost::asio::local::stream_protocol::socket & s,
352 boost::system::error_code & ec)
353 {
354 std::unique_lock lck(_mtx);
355 return ASIO::Read(s, _map, ec);
356 }
357
358 //------------------------------------------------------------------------
361 //------------------------------------------------------------------------
362 bool Write(boost::asio::local::stream_protocol::socket & s,
363 boost::system::error_code & ec) const
364 {
365 std::shared_lock lck(_mtx);
366 return ASIO::Write(s, _map, ec);
367 }
368
369 //------------------------------------------------------------------------
372 //------------------------------------------------------------------------
373 bool Read(boost::asio::generic::stream_protocol::socket & s,
374 boost::system::error_code & ec)
375 {
376 std::unique_lock lck(_mtx);
377 return ASIO::Read(s, _map, ec);
378 }
379
380 //------------------------------------------------------------------------
383 //------------------------------------------------------------------------
384 bool Write(boost::asio::generic::stream_protocol::socket & s,
385 boost::system::error_code & ec) const
386 {
387 std::shared_lock lck(_mtx);
388 return ASIO::Write(s, _map, ec);
389 }
390
391 //------------------------------------------------------------------------
393 //------------------------------------------------------------------------
394 std::shared_lock<std::shared_mutex> SharedLock() const
395 {
396 return std::shared_lock(_mtx);
397 }
398
399 //------------------------------------------------------------------------
401 //------------------------------------------------------------------------
402 std::unique_lock<std::shared_mutex> UniqueLock()
403 {
404 return std::unique_lock(_mtx);
405 }
406
407 private:
408 mutable std::shared_mutex _mtx;
409 std::unordered_map<Ipv6Address,T,Hash> _map;
410
411 //------------------------------------------------------------------------
413 //------------------------------------------------------------------------
414 bool FindNoLock(const Ipv6Address & addr, T & value) const
415 {
416 auto iter = _map.find(addr);
417 if (iter != _map.end()) {
418 value = iter->second;
419 return true;
420 }
421 return false;
422 }
423
424 };
425
426} // namespace Dwm
427
428#endif // _DWMIPV6ADDRMAP_HH_
Dwm::ASIO class declaration.
Dwm::BZ2IO class declaration.
Dwm::DescriptorIO class declaration.
Dwm::FileIO class declaration.
Dwm::GZIO class definition.
Dwm::IOUtils class declaration and implementation.
Dwm::Ipv6Address class definition.
Dwm::StreamIO class declaration.
static bool Write(boost::asio::ip::tcp::socket &s, uint8_t value, boost::system::error_code &ec)
Write value to the given socket s.
static bool Read(boost::asio::ip::tcp::socket &s, uint8_t &value, boost::system::error_code &ec)
Reads value from the given socket s.
static int BZRead(BZFILE *bzf, char &c)
Reads from bzf.
static int BZWrite(BZFILE *bzf, char c)
Writes c to bzf.
static ssize_t Write(int fd, char c)
Writes c to fd.
static ssize_t Read(int fd, char &c)
Reads c from fd.
static size_t Write(FILE *f, char c)
Writes c to f.
static size_t Read(FILE *f, char &c)
Reads c from f.
static int Write(gzFile gzf, char c)
Writes c to gzf.
static int Read(gzFile gzf, char &c)
Reads from gzf.
static uint64_t StreamedLength(char c)
Returns the number of bytes that would be written if we called Write() for a char.
Definition DwmIOUtils.hh:85
A thin wrapper around std::unordered_map<Ipv6Address,T,Hash>.
Definition DwmIpv6AddrMap.hh:77
std::istream & Read(std::istream &is)
Reads the Ipv6AddrMap from an istream. Returns the istream.
Definition DwmIpv6AddrMap.hh:212
int BZWrite(BZFILE *bzf) const
Writes the Ipv6AddrMap to bzf.
Definition DwmIpv6AddrMap.hh:309
size_t Read(FILE *f)
Reads the Ipv6AddrMap from f.
Definition DwmIpv6AddrMap.hh:231
ssize_t Write(int fd) const
Writes the Ipv6AddrMap to file descriptor fd.
Definition DwmIpv6AddrMap.hh:261
std::ostream & Write(std::ostream &os) const
Writes the Ipv6AddrMap to an ostream. Returns the ostream.
Definition DwmIpv6AddrMap.hh:221
int Read(gzFile gzf)
Reads the Ipv6AddrMap from gzf.
Definition DwmIpv6AddrMap.hh:273
bool Write(boost::asio::ip::tcp::socket &s, boost::system::error_code &ec) const
Writes the Ipv6AddrMap to s.
Definition DwmIpv6AddrMap.hh:340
bool Read(boost::asio::ip::tcp::socket &s, boost::system::error_code &ec)
Reads the Ipv6AddrMap from s.
Definition DwmIpv6AddrMap.hh:329
bool Write(boost::asio::generic::stream_protocol::socket &s, boost::system::error_code &ec) const
Writes the Ipv6AddrMap to s.
Definition DwmIpv6AddrMap.hh:384
int Write(gzFile gzf) const
Writes the Ipv6AddrMap to gzf.
Definition DwmIpv6AddrMap.hh:285
bool Read(boost::asio::local::stream_protocol::socket &s, boost::system::error_code &ec)
Reads the Ipv6AddrMap from s.
Definition DwmIpv6AddrMap.hh:351
size_t Write(FILE *f) const
Writes the Ipv6AddrMap to f.
Definition DwmIpv6AddrMap.hh:241
int BZRead(BZFILE *bzf)
Reads the Ipv6AddrMap from bzf.
Definition DwmIpv6AddrMap.hh:297
bool Read(boost::asio::generic::stream_protocol::socket &s, boost::system::error_code &ec)
Reads the Ipv6AddrMap from s.
Definition DwmIpv6AddrMap.hh:373
uint64_t StreamedLength() const
Returns the number of bytes that would be written if the Ipv6AddrMap was written to a FILE,...
Definition DwmIpv6AddrMap.hh:319
bool Write(boost::asio::local::stream_protocol::socket &s, boost::system::error_code &ec) const
Writes the Ipv6AddrMap to s.
Definition DwmIpv6AddrMap.hh:362
ssize_t Read(int fd)
Reads the Ipv6AddrMap from file descriptor fd.
Definition DwmIpv6AddrMap.hh:251
This class encapsulates an IPv6 address.
Definition DwmIpv6Address.hh:64
uint64_t Hash() const
Returns a 64-bit hash value for the Ipv6Address.
Definition DwmIpv6Address.hh:289
static std::istream & Read(std::istream &is, char &c)
Reads c from is. Returns is.
static std::ostream & Write(std::ostream &os, char c)
Writes c to os. Returns os.