<commit_before>//! A simple timer, used to enqueue operations meant to be executed at
//! a given time or after a given delay.

extern crate chrono;

use std::cmp::Ordering;
use std::thread;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering as AtomicOrdering;
use std::sync::{Arc, Mutex, Condvar};
use std::sync::mpsc::{channel, Sender};
use std::collections::BinaryHeap;
use chrono::{Duration, DateTime};
use chrono::offset::Utc;

/// An item scheduled for delayed execution.
struct Schedule<T> {
    /// The instant at which to execute.
    date: DateTime<Utc>,

    /// The schedule data.
    data : T,

    /// A mechanism to cancel execution of an item.
    guard: Guard,

    /// If `Some(d)`, the item must be repeated every interval of
    /// length `d`, until cancelled.
    repeat: Option<Duration>
}
impl <T> Ord for Schedule<T> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.date.cmp(&other.date).reverse()
    }
}
impl <T> PartialOrd for Schedule<T> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.date.partial_cmp(&other.date).map(|ord| ord.reverse())
    }
}
impl <T> Eq for Schedule<T> {
}
impl <T> PartialEq for Schedule<T> {
    fn eq(&self, other: &Self) -> bool {
        self.date.eq(&other.date)
    }
}

/// An operation to be sent across threads.
enum Op<T> {
    /// Schedule a new item for execution.
    Schedule(Schedule<T>),

    /// Stop the thread.
    Stop
}

/// A mutex-based kind-of-channel used to communicate between the
/// Communication thread and the Scheuler thread.
struct WaiterChannel<T> {
    /// Pending messages.
    messages: Mutex<Vec<Op<T>>>,
    /// A condition variable used for waiting.
    condvar: Condvar,
}
impl <T> WaiterChannel<T> {
    fn with_capacity(cap: usize) -> Self {
        WaiterChannel {
            messages: Mutex::new(Vec::with_capacity(cap)),
            condvar: Condvar::new(),
        }
    }
}

/// A trait that allows configurable execution of scheduled item
/// on the scheduler thread.
trait Executor<T> {
    // Due to difference in use between Box<FnMut()> and most other data
    // types, this trait requires implementors to provide two implementations
    // of execute. While both of these functions execute the data item
    // they differ on whether they make an equivalent data item available
    // to the Scheduler to store in recurring schedules.
    //
    // execute() is called whenever a non-recurring data item needs
    // to be executed, and consumes the data item in the process.
    //
    // execute_clone() is called whenever a recurring data item needs
    // to be executed, and produces a new equivalent data item. This
    // function should be more or less equivalent to:
    //
    // fn execute_clone(&mut self, data : T) -> T {
    //   self.execute(data.clone());
    //   data
    // }

    fn execute(&mut self, data : T);

    fn execute_clone(&mut self, data : T) -> T;
}

/// An executor implementation for executing callbacks on the scheduler
/// thread.
struct CallbackExecutor;

impl Executor<Box<FnMut() + Send>> for CallbackExecutor {
    fn execute(&mut self, mut data : Box<FnMut() + Send>) {<commit_msg>trait objects without an explicit `dyn` are deprecated<commit_after>//! A simple timer, used to enqueue operations meant to be executed at
//! a given time or after a given delay.

extern crate chrono;

use std::cmp::Ordering;
use std::thread;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering as AtomicOrdering;
use std::sync::{Arc, Mutex, Condvar};
use std::sync::mpsc::{channel, Sender};
use std::collections::BinaryHeap;
use chrono::{Duration, DateTime};
use chrono::offset::Utc;

/// An item scheduled for delayed execution.
struct Schedule<T> {
    /// The instant at which to execute.
    date: DateTime<Utc>,

    /// The schedule data.
    data : T,

    /// A mechanism to cancel execution of an item.
    guard: Guard,

    /// If `Some(d)`, the item must be repeated every interval of
    /// length `d`, until cancelled.
    repeat: Option<Duration>
}
impl <T> Ord for Schedule<T> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.date.cmp(&other.date).reverse()
    }
}
impl <T> PartialOrd for Schedule<T> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.date.partial_cmp(&other.date).map(|ord| ord.reverse())
    }
}
impl <T> Eq for Schedule<T> {
}
impl <T> PartialEq for Schedule<T> {
    fn eq(&self, other: &Self) -> bool {
        self.date.eq(&other.date)
    }
}

/// An operation to be sent across threads.
enum Op<T> {
    /// Schedule a new item for execution.
    Schedule(Schedule<T>),

    /// Stop the thread.
    Stop
}

/// A mutex-based kind-of-channel used to communicate between the
/// Communication thread and the Scheuler thread.
struct WaiterChannel<T> {
    /// Pending messages.
    messages: Mutex<Vec<Op<T>>>,
    /// A condition variable used for waiting.
    condvar: Condvar,
}
impl <T> WaiterChannel<T> {
    fn with_capacity(cap: usize) -> Self {
        WaiterChannel {
            messages: Mutex::new(Vec::with_capacity(cap)),
            condvar: Condvar::new(),
        }
    }
}

/// A trait that allows configurable execution of scheduled item
/// on the scheduler thread.
trait Executor<T> {
    // Due to difference in use between Box<FnMut()> and most other data
    // types, this trait requires implementors to provide two implementations
    // of execute. While both of these functions execute the data item
    // they differ on whether they make an equivalent data item available
    // to the Scheduler to store in recurring schedules.
    //
    // execute() is called whenever a non-recurring data item needs
    // to be executed, and consumes the data item in the process.
    //
    // execute_clone() is called whenever a recurring data item needs
    // to be executed, and produces a new equivalent data item. This
    // function should be more or less equivalent to:
    //
    // fn execute_clone(&mut self, data : T) -> T {
    //   self.execute(data.clone());
    //   data
    // }

    fn execute(&mut self, data : T);

    fn execute_clone(&mut self, data : T) -> T;
}

/// An executor implementation for executing callbacks on the scheduler
/// thread.
struct CallbackExecutor;

impl Executor<Box<dyn FnMut() + Send>> for CallbackExecutor {
    fn execute(&mut self, mut data : Box<FnMut() + Send>) {
{'fraction_non_alphanumeric': 0.12571962035164153, 'fraction_numerical': 0.0, 'mean_word_length': 2.8886872353297037, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5160580', 'n_tokens_mistral': 1911, 'n_tokens_neox': 1890, 'n_words': 708}