【trick】A variant of token bucket implementation
1 struct TokenBucket 2 { 3 uint64_t fill_interval_; 4 uint64_t gen_interval_; 5 uint64_t reset_time_; 6 // reset_time_ is equivalent to last_consume_time + token_num and 7 // the calculated token num is auto renormalized on limit change. 8 9 TokenBucket() 10 : fill_interval_(0) 11 , gen_interval_(0) 12 , reset_time_(0) {} 13 14 // eg, for 10req/30s, capacity=10, period=30 15 void set_limit(uint64_t capacity, uint64_t period) 16 { 17 fill_interval_ = period; 18 gen_interval_ = period / capacity; 19 } 20 21 bool consume(unsigned num) 22 { 23 uint64_t curr_time = get_monotonic_time(); 24 uint64_t new_reset_time = std::max(reset_time_, curr_time - fill_interval_) + gen_interval_ * num; 25 if (curr_time >= new_reset_time) 26 { 27 reset_time_ = new_reset_time; // reset_time_ is monotonic increasing 28 return true; 29 } 30 return false; 31 } 32 };