//函数参数只有两个,分别是采样结构体的指针和本次采样下载的数据量 int64_t SDL_SpeedSampler2Add(SDL_SpeedSampler2 *sampler, int quantity) { if (quantity < 0 ) return 0 ; int64_t sample_range = sampler->sample_range; int64_t last_tick = sampler->last_profile_tick; int64_t last_duration = sampler->last_profile_duration; int64_t last_quantity = sampler->last_profile_quantity; int64_t now = (int64_t)SDL_GetTickHR(); //这里使用两次采样的间隔作为本次采样的下载时间 int64_t elapsed = (int64_t)llabs(now - last_tick); //如果两次采样的间隔时间超过了sample_range,那么之前的采样信息便不再置信,因此需要重新统计采样信息,将本次采样作为第一次采样 if (elapsed < 0 || elapsed >= sample_range) { // overflow, reset to initialized state sampler->last_profile_tick = now; sampler->last_profile_duration = sample_range; sampler->last_profile_quantity = quantity; sampler->last_profile_speed = quantity * 1000 / sample_range; return sampler->last_profile_speed; } //这里就是加权算法的部分,这里的last_quantity和last_duration都是从0开始增长的,即new_quantity和new_duration也是从0开始增长的。当new_duration小于sample_range时, //即第一个采样点与最后一个采样点的时间差在sample_range范围内时,new_duration和new_quantity的权重都还是1,即未经过加权;一旦new_duration大于sample_range后,new_duration //的值就会被固定为sample_range,new_quantity则按比例进行缩小,这也就变相地实现了,越靠前的采样点,随着时间的推移,所占的比重会越来越小。 int64_t new_quantity = last_quantity + quantity; int64_t new_duration = last_duration + elapsed; if (new_duration > sample_range) { new_quantity = new_quantity * sample_range / new_duration; new_duration = sample_range; } //这部分逻辑比较简单了,更新变量然后算出当前平均带宽。 sampler->last_profile_tick = now; sampler->last_profile_duration = new_duration; sampler->last_profile_quantity = new_quantity; if (new_duration > 0 ) sampler->last_profile_speed = new_quantity * 1000 / new_duration; return sampler->last_profile_speed; } |