use otel_arrow_dfe_config::ExtensionId;
use std::any::TypeId;
use std::cell::Cell;
use std::collections::{HashMap, HashSet};
use std::rc::Rc;
pub(crate) struct ConsumedTracker {
local: HashMap<(TypeId, ExtensionId), ConsumedEntry>,
shared: HashMap<(TypeId, ExtensionId), ConsumedEntry>,
}
impl std::fmt::Debug for ConsumedTracker {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConsumedTracker")
.field("local_slots", &self.local.len())
.field("shared_slots", &self.shared.len())
.finish()
}
}
pub(crate) struct ConsumedEntry {
#[allow(dead_code)]
pub(crate) name: &'static str,
pub(crate) extension_id: ExtensionId,
pub(crate) consumed: Rc<Cell<bool>>,
}
impl ConsumedTracker {
pub(crate) fn new() -> Self {
ConsumedTracker {
local: HashMap::new(),
shared: HashMap::new(),
}
}
pub(crate) fn ensure_local_consumer_slot(
&mut self,
capability_id: TypeId,
name: &'static str,
extension_id: ExtensionId,
) -> Rc<Cell<bool>> {
let entry = self
.local
.entry((capability_id, extension_id.clone()))
.or_insert_with(|| ConsumedEntry {
name,
extension_id,
consumed: Rc::new(Cell::new(false)),
});
Rc::clone(&entry.consumed)
}
pub(crate) fn ensure_shared_consumer_slot(
&mut self,
capability_id: TypeId,
name: &'static str,
extension_id: ExtensionId,
) -> Rc<Cell<bool>> {
let entry = self
.shared
.entry((capability_id, extension_id.clone()))
.or_insert_with(|| ConsumedEntry {
name,
extension_id,
consumed: Rc::new(Cell::new(false)),
});
Rc::clone(&entry.consumed)
}
#[allow(dead_code)]
pub(crate) fn unconsumed_local(&self) -> Vec<(ExtensionId, &'static str)> {
self.local
.values()
.filter(|e| !e.consumed.get())
.map(|e| (e.extension_id.clone(), e.name))
.collect()
}
#[allow(dead_code)]
pub(crate) fn unconsumed_shared(&self) -> Vec<(ExtensionId, &'static str)> {
self.shared
.values()
.filter(|e| !e.consumed.get())
.map(|e| (e.extension_id.clone(), e.name))
.collect()
}
pub(crate) fn consumed_local(&self) -> HashSet<ExtensionId> {
self.local
.values()
.filter(|e| e.consumed.get())
.map(|e| e.extension_id.clone())
.collect()
}
pub(crate) fn consumed_shared(&self) -> HashSet<ExtensionId> {
self.shared
.values()
.filter(|e| e.consumed.get())
.map(|e| e.extension_id.clone())
.collect()
}
}