接着上一篇博客,现在分析DNSCache.h文件中的内容,“LRUCache.h"已经分析过了,它还包含"platformSocket.h",代码比较简洁,定义了不同平台实现网络间通信需要的结构体、头文件。
#ifndef _PLATFORMSOCKET_H_
#define _PLATFORMSOCKET_H_
#include <sys/types.h>
#ifdef _WIN32
# include <Ws2tcpip.h>
# include <Ws2def.h>
/*
typedef struct _WSABUF {
ULONG len;
CHAR *buf;
} WSABUF, *LPWSABUF;
*/
struct iovec
{
void *iov_base;
size_t iov_len;
};
#else
# include <arpa/inet.h>
# include <sys/socket.h>
# include <sys/un.h>
# include <sys/uio.h>
# include <netdb.h>
#endif
#endif
#indef_WIN32 ... #else ...这样的写法是为了方便代码在不同的平台(Windows、Linux)之间移植,根据不同的平台设计不同的diamante。符合workflow的可移植性。TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字。#include<Ws2tcpip.h>以及Linux下对等的这些头文件是为了实现网络间通信。
结构体iovec定义了一个向量元素,指针成员iov_base指向一个缓冲区,这个缓冲区存放的是要接受的数据或者要发送的数据,io v_len可以确定为可以接受的最大长度以及实际写入的长度。
public:
using HostPort = std::pair<std::string, unsigned short>;
using DNSHandle = LRUHandle<HostPort, DNSCacheValue>;
类中的两个公开成员hostPort、DNSHandle的定义。using在这里是为了类型重命名,std:pair主要的作用是将两个数据合成为一个数据,数据类型可以相同也可以不同,与结构体实质一样。初始化一个pair可以使用构造函数,也可以使用std:make_pair函数:
template pair make_pair(T1 a, T2 b) { return pair(a, b); }
类中的私有成员,mutex控制访问cache的线程数量,它协调各个线程,保证合理地使用公共资源。void operator() (const DNSCacheValue& value) const 是对“()”进行重载操作,
由getaddrinfo返回的存储空间,包括addrinfo结构、ai_addr结构等,都是用malloc动态获取的。调用freeaddrinfo可将这些存储空间返回给系统,需要头文件#include <netdb.h>。
private:
const DNSHandle *get_inner(const HostPort& host_port, int type);
std::mutex mutex_;
class ValueDeleter
{
public:
void operator() (const DNSCacheValue& value) const
{
freeaddrinfo(value.addrinfo);
}
};
LRUCache<HostPort, DNSCacheValue, ValueDeleter> cache_pool_;
接下来看类中实现了哪些函数, 总共有release、*get、*get_ttl、*get_confident、*put、del这几个方法,具体根据传入参数的不同又分别重载了几个同名的函数,观察函数体,实现的逻辑基一致。
void release(DNSHandle *handle)
{
cache_pool_.release(handle);
}
void release(const DNSHandle *handle)
{
cache_pool_.release(handle);
}
const DNSHandle *get(const HostPort& host_port)
{
return cache_pool_.get(host_port);
}
const DNSHandle *get(const std::string& host, unsigned short port)
{
return get(HostPort(host, port));
}
const DNSHandle *get(const char *host, unsigned short port)
{
return get(std::string(host), port);
}
const DNSHandle *get_ttl(const HostPort& host_port)
{
return get_inner(host_port, GET_TYPE_TTL);
}
const DNSHandle *get_ttl(const std::string& host, unsigned short port)
{
return get_ttl(HostPort(host, port));
}
const DNSHandle *get_ttl(const char *host, unsigned short port)
{
return get_ttl(std::string(host), port);
}
const DNSHandle *get_confident(const HostPort& host_port)
{
return get_inner(host_port, GET_TYPE_CONFIDENT);
}
const DNSHandle *get_confident(const std::string& host, unsigned short port)
{
return get_confident(HostPort(host, port));
}
const DNSHandle *get_confident(const char *host, unsigned short port)
{
return get_confident(std::string(host), port);
}
const DNSHandle *put(const HostPort& host_port,
struct addrinfo *addrinfo,
unsigned int dns_ttl_default,
unsigned int dns_ttl_min);
const DNSHandle *put(const std::string& host,
unsigned short port,
struct addrinfo *addrinfo,
unsigned int dns_ttl_default,
unsigned int dns_ttl_min)
{
return put(HostPort(host, port), addrinfo, dns_ttl_default, dns_ttl_min);
}
const DNSHandle *put(const char *host,
unsigned short port,
struct addrinfo *addrinfo,
unsigned int dns_ttl_default,
unsigned int dns_ttl_min)
{
return put(std::string(host), port, addrinfo, dns_ttl_default, dns_ttl_min);
}
void del(const HostPort& key)
{
cache_pool_.del(key);
}
void del(const std::string& host, unsigned short port)
{
del(HostPort(host, port));
}
void del(const char *host, unsigned short port)
{
del(std::string(host), port);
}
cache_pool是LRUCache类的对象,在上篇博客中分析过LRUCache这个类,明白LRU算法的思想,这里就容易理解了。
参考资料:
(40条消息) C++编程时#ifdef _WIN32的作用_三又三分之一年的博客-CSDN博客
(40条消息) iovec结构体定义及使用_tym8865的专栏-CSDN博客
C++关键字之using的的用法总结 - 小念之歌 - 博客园 (cnblogs.com)