tdlight/td/telegram/files/ResourceState.h
2021-01-01 15:57:46 +03:00

115 lines
2.9 KiB
C++

//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once
#include "td/utils/common.h"
#include "td/utils/format.h"
#include "td/utils/StringBuilder.h"
namespace td {
class ResourceState {
public:
void start_use(int64 x) {
using_ += x;
CHECK(used_ + using_ <= limit_);
}
void stop_use(int64 x) {
CHECK(x <= using_);
using_ -= x;
used_ += x;
}
void update_limit(int64 extra) {
limit_ += extra;
}
bool update_estimated_limit(int64 extra) {
// unused() must be positive, i.e. used_ + using_ must be less than limit_
// TODO: use exact intersection between using_ and extra.
auto using_and_extra_intersection = min(using_, extra); // between 0 and min(using_, extra)
auto new_estimated_limit = used_ + using_ + extra - using_and_extra_intersection;
// Use extra extra limit
if (new_estimated_limit < limit_) {
auto extra_limit = limit_ - new_estimated_limit;
used_ += extra_limit;
new_estimated_limit += extra_limit;
}
if (new_estimated_limit == estimated_limit_) {
return false;
}
estimated_limit_ = new_estimated_limit;
return true;
}
void set_unit_size(size_t new_unit_size) {
unit_size_ = new_unit_size;
}
int64 active_limit() const {
return limit_ - used_;
}
int64 get_using() const {
return using_;
}
int64 unused() const {
return limit_ - using_ - used_;
}
int64 estimated_extra() const {
auto new_unused = max(limit_, estimated_limit_) - using_ - used_;
new_unused = static_cast<int64>((new_unused + unit_size() - 1) / unit_size() * unit_size());
return new_unused + using_ + used_ - limit_;
}
size_t unit_size() const {
return unit_size_;
}
ResourceState &operator+=(const ResourceState &other) {
using_ += other.active_limit();
used_ += other.used_;
return *this;
}
ResourceState &operator-=(const ResourceState &other) {
using_ -= other.active_limit();
used_ -= other.used_;
return *this;
}
void update_master(const ResourceState &other) {
estimated_limit_ = other.estimated_limit_;
used_ = other.used_;
using_ = other.using_;
unit_size_ = other.unit_size_;
}
void update_slave(const ResourceState &other) {
limit_ = other.limit_;
}
friend StringBuilder &operator<<(StringBuilder &sb, const ResourceState &state) {
return sb << tag("estimated_limit", state.estimated_limit_) << tag("used", state.used_)
<< tag("using", state.using_) << tag("limit", state.limit_);
}
private:
int64 estimated_limit_ = 0; // me
int64 limit_ = 0; // master
int64 used_ = 0; // me
int64 using_ = 0; // me
size_t unit_size_ = 1; // me
};
} // namespace td