9746: internal: add API to check what are the max limits in practice r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2021-07-31 15:27:11 +00:00 committed by GitHub
commit eb513c22f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 4 deletions

View file

@ -22,7 +22,9 @@ use crate::{
///
/// If an invocation produces more tokens than this limit, it will not be stored in the database and
/// an error will be emitted.
const TOKEN_LIMIT: Limit = Limit::new(524288);
///
/// Actual max for `analysis-stats .` at some point: 30672.
static TOKEN_LIMIT: Limit = Limit::new(524_288);
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum TokenExpander {

View file

@ -6,4 +6,6 @@ license = "MIT OR Apache-2.0"
authors = ["rust-analyzer developers"]
edition = "2018"
[dependencies]
[features]
tracking = []
default = ["tracking"]

View file

@ -1,15 +1,26 @@
//! limit defines a struct to enforce limits.
use std::sync::atomic::AtomicUsize;
/// Represents a struct used to enforce a numerical limit.
pub struct Limit {
upper_bound: usize,
#[allow(unused)]
max: AtomicUsize,
}
impl Limit {
/// Creates a new limit.
#[inline]
pub const fn new(upper_bound: usize) -> Self {
Self { upper_bound }
Self { upper_bound, max: AtomicUsize::new(0) }
}
/// Creates a new limit.
#[inline]
#[cfg(feature = "tracking")]
pub const fn new_tracking(upper_bound: usize) -> Self {
Self { upper_bound, max: AtomicUsize::new(1) }
}
/// Gets the underlying numeric limit.
@ -21,10 +32,26 @@ impl Limit {
/// Checks whether the given value is below the limit.
/// Returns `Ok` when `other` is below `self`, and `Err` otherwise.
#[inline]
pub const fn check(&self, other: usize) -> Result<(), ()> {
pub fn check(&self, other: usize) -> Result<(), ()> {
if other > self.upper_bound {
Err(())
} else {
#[cfg(feature = "tracking")]
loop {
use std::sync::atomic::Ordering;
let old_max = self.max.load(Ordering::Relaxed);
if other <= old_max || old_max == 0 {
break;
}
if self
.max
.compare_exchange(old_max, other, Ordering::Relaxed, Ordering::Relaxed)
.is_ok()
{
eprintln!("new max: {}", other);
}
}
Ok(())
}
}