当前位置: 首页 > 工具软件 > dnscache > 使用案例 >

workflow(4)DNSCache(3)

洪弘壮
2023-12-01

2021SC@SDUSC

DNSCache.cc

    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博客

 类似资料: