blob: 762fe1edfbd407a2d02f52eefabd6fa596ea6707 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#pragma once
#include <dsn/dist/replication/replication.codes.h>
namespace pegasus {
namespace server {
class pegasus_server_impl;
struct range_read_limiter_options
{
uint32_t multi_get_max_iteration_count;
uint64_t multi_get_max_iteration_size;
uint32_t rocksdb_max_iteration_count;
uint64_t rocksdb_iteration_threshold_time_ms_in_config;
uint64_t rocksdb_iteration_threshold_time_ms;
};
class range_read_limiter
{
public:
range_read_limiter(uint32_t max_iteration_count,
uint64_t max_iteration_size,
uint64_t threshold_time_ms)
: _max_count(max_iteration_count), _max_size(max_iteration_size)
{
_module_num = _max_count <= 10 ? 1 : _max_count / 10;
_max_duration_time = threshold_time_ms > 0 ? threshold_time_ms * 1e6 : 0;
_iteration_start_time_ns = dsn_now_ns();
}
bool valid()
{
if (_iteration_count >= _max_count) {
return false;
}
if (_max_size > 0 && _iteration_size >= _max_size) {
return false;
}
return time_check();
}
// during rocksdb iteration, if iteration_count % module_num == 0, we will check if iteration
// exceed time threshold, which means we at most check ten times during iteration
bool time_check()
{
if (_max_duration_time > 0 && (_iteration_count + 1) % _module_num == 0 &&
dsn_now_ns() - _iteration_start_time_ns > _max_duration_time) {
_exceed_limit = true;
_iteration_duration_time_ns = dsn_now_ns() - _iteration_start_time_ns;
return false;
}
return true;
}
void time_check_after_incomplete_scan()
{
if (_max_duration_time > 0 &&
dsn_now_ns() - _iteration_start_time_ns > _max_duration_time) {
_exceed_limit = true;
_iteration_duration_time_ns = dsn_now_ns() - _iteration_start_time_ns;
}
}
void add_count() { ++_iteration_count; }
void add_size(uint64_t size) { _iteration_size += size; }
bool exceed_limit() { return _exceed_limit; }
uint32_t get_iteration_count() { return _iteration_count; }
uint64_t duration_time() { return _iteration_duration_time_ns; }
uint64_t max_duration_time() { return _max_duration_time; }
private:
bool _exceed_limit{false};
uint32_t _iteration_count{0};
uint64_t _iteration_size{0};
uint64_t _iteration_start_time_ns{0};
uint64_t _iteration_duration_time_ns{0};
uint32_t _max_count{0};
uint64_t _max_size{0};
uint64_t _max_duration_time{0};
int32_t _module_num{1};
};
} // namespace server
} // namespace pegasus