DNSCache文件中主要实现了两个函数get_inner(const HostPort& host_port, int type)和put(const HostPort& host_port, struct addrinfo *addrinfo,unsigned int dns_ttl_default,unsigned int dns_ttl_min),这两者在DNSCache.h文件中都已经声明。
put在项目中根据传入参数的不同重载了多种不同的形式,实际上都是调用的下面这个函数。
const DNSCache::DNSHandle *DNSCache::put(const HostPort& host_port,
struct addrinfo *addrinfo,
unsigned int dns_ttl_default,
unsigned int dns_ttl_min)
{
int64_t expire_time;
int64_t confident_time;
int64_t cur_time = GET_CURRENT_SECOND;
if (dns_ttl_min > dns_ttl_default)
dns_ttl_min = dns_ttl_default;
if (dns_ttl_min == (unsigned int)-1)
confident_time = INT64_MAX;
else
confident_time = cur_time + dns_ttl_min;
if (dns_ttl_default == (unsigned int)-1)
expire_time = INT64_MAX;
else
expire_time = cur_time + dns_ttl_default;
std::lock_guard<std::mutex> lock(mutex_);
return cache_pool_.put(host_port, {addrinfo, confident_time, expire_time});
}
std::chrono是c++中一个时间库,duration_cast显然是类型转换,将参数转换为其它持续时间类型,同时考虑其周期的差异;steady_clock表示从未调整的时钟,并且以统一的速度向前移动,第一次调用返回的值始终小于或等于下一次调用返回的值。 now()方法不难看出用来返回当前时间,time_since_epoch 用来获取时间,count返回持续时间类型。
#define GET_CURRENT_SECOND std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now().time_since_epoch()).count()
dns_ttl_default为DNSCache中默认的数据记录在缓存块上的时间,若无任合声明为12h,第一篇博客中提到过。INT64_MAX,应该是指64位int类型最大的数值,这样处理是为了方便程序在不同平台上运行。expire_time我理解成Cache上信息的保存时间。confident_time我暂时理解为Cache中内容可信的时间。
最后一行调用的是LRUCache类的put方法,该方法在第二篇博客中介绍过,方法定义为const Handle *put(const KEY& key, VALUE value),这里就不重复了。在LRUCache类中,对cache块的key值和value做了模板定义。
template<typename KEY, typename VALUE>
在这里cache块的key值就是主机端口号,value是{addrinfo, confident_time, expire_time},这三个属性组成的 DNSCacheValue 结构体,在第二篇博客也有介绍。
const DNSCache::DNSHandle *DNSCache::get_inner(const HostPort& host_port, int type)
{
const DNSHandle *handle = cache_pool_.get(host_port);
if (handle)
{
int64_t cur_time = GET_CURRENT_SECOND;
switch (type)
{
case GET_TYPE_TTL:
if (cur_time > handle->value.expire_time)
{
std::lock_guard<std::mutex> lock(mutex_);
if (cur_time > handle->value.expire_time)
{
const_cast<DNSHandle *>(handle)->value.expire_time += TTL_INC;
cache_pool_.release(handle);
return NULL;
}
}
break;
case GET_TYPE_CONFIDENT:
if (cur_time > handle->value.confident_time)
{
std::lock_guard<std::mutex> lock(mutex_);
if (cur_time > handle->value.confident_time)
{
const_cast<DNSHandle *>(handle)->value.confident_time += CONFIDENT_INC;
cache_pool_.release(handle);
return NULL;
}
}
break;
default:
break;
}
}
return handle;
}
上面是get_inner(const HostPort& host_port, int type), 该函数从cache块中取出数据,根据传入类型的不同,可以分别得到expire_time和confident_time, 如果发现要取的数据保存在cache上的时间超过了默认的值(或者是程序员设定的值),该函数还负责将该块移出去,并返回空值(因为数据可能是dirty的)。
参考资料:
duration_cast - C++参考 (cplusplus.com)
steady_clock|微软文档 (microsoft.com)
std::chrono::steady_clock::now - C++中文 - API参考文档 (apiref.com)
(49条消息) c++11 chrono全面解析(最高可达纳秒级别的精度)_帝江VII的博客-CSDN博客_chrono 纳秒
(49条消息) C++11 std::chrono时间库及应用(打印程序耗时等)_qfturauyls的博客-CSDN博客