use super::request::SpiderRequest;
use std::collections::{BinaryHeap, HashSet};
pub struct Scheduler {
queue: BinaryHeap<SpiderRequest>,
seen: HashSet<String>,
include_kwargs: bool,
include_headers: bool,
keep_fragments: bool,
}
impl Scheduler {
pub fn new(include_kwargs: bool, include_headers: bool, keep_fragments: bool) -> Self {
Self {
queue: BinaryHeap::new(),
seen: HashSet::new(),
include_kwargs,
include_headers,
keep_fragments,
}
}
pub fn enqueue(&mut self, mut request: SpiderRequest) -> bool {
request.update_fingerprint(
self.include_kwargs,
self.include_headers,
self.keep_fragments,
);
if !request.dont_filter() {
let fp = request.fingerprint().to_string();
if self.seen.contains(&fp) {
return false;
}
self.seen.insert(fp);
}
self.queue.push(request);
true
}
pub fn dequeue(&mut self) -> Option<SpiderRequest> {
self.queue.pop()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.queue.is_empty()
}
#[must_use]
pub fn len(&self) -> usize {
self.queue.len()
}
#[must_use]
pub fn seen_count(&self) -> usize {
self.seen.len()
}
pub fn clear(&mut self) {
self.queue.clear();
self.seen.clear();
}
#[must_use]
pub fn pending_requests(&self) -> Vec<&SpiderRequest> {
self.queue.iter().collect()
}
pub fn snapshot(&self) -> (Vec<SpiderRequest>, Vec<String>) {
let pending = self.queue.iter().cloned().collect();
let seen = self.seen.iter().cloned().collect();
(pending, seen)
}
pub fn restore_seen(&mut self, fingerprints: impl IntoIterator<Item = String>) {
self.seen.extend(fingerprints);
}
}