use std::collections::HashMap;
use smallvec::SmallVec;
use sqry_core::graph::unified::concurrent::GraphSnapshot;
use sqry_core::graph::unified::file::id::FileId;
use sqry_core::graph::unified::node::id::NodeId;
#[derive(Debug, Clone)]
pub struct FileInput {
pub node_ids: SmallVec<[NodeId; 16]>,
pub revision: u64,
}
impl FileInput {
#[must_use]
pub fn new(node_ids: SmallVec<[NodeId; 16]>) -> Self {
Self {
node_ids,
revision: 1,
}
}
#[inline]
#[must_use]
pub fn revision(&self) -> u64 {
self.revision
}
pub fn update(&mut self, new_node_ids: SmallVec<[NodeId; 16]>) {
self.revision = self.revision.saturating_add(1);
self.node_ids = new_node_ids;
}
}
#[derive(Debug, Clone)]
pub struct FileInputStore {
entries: HashMap<FileId, FileInput>,
}
impl FileInputStore {
#[must_use]
pub fn new() -> Self {
Self {
entries: HashMap::new(),
}
}
#[must_use]
pub fn from_snapshot(snapshot: &GraphSnapshot) -> Self {
let mut file_nodes: HashMap<FileId, SmallVec<[NodeId; 16]>> = HashMap::new();
let arena = snapshot.nodes();
for (idx, slot) in arena.slots().iter().enumerate() {
if let Some(entry) = slot.get() {
let file_id = entry.file;
if file_id != FileId::INVALID {
let node_id = NodeId::new(idx as u32, slot.generation());
file_nodes.entry(file_id).or_default().push(node_id);
}
}
}
let entries = file_nodes
.into_iter()
.map(|(fid, nodes)| (fid, FileInput::new(nodes)))
.collect();
Self { entries }
}
#[inline]
#[must_use]
pub fn revision(&self, file_id: FileId) -> Option<u64> {
self.entries.get(&file_id).map(|fi| fi.revision)
}
#[inline]
#[must_use]
pub fn get(&self, file_id: FileId) -> Option<&FileInput> {
self.entries.get(&file_id)
}
#[inline]
pub fn get_mut(&mut self, file_id: FileId) -> Option<&mut FileInput> {
self.entries.get_mut(&file_id)
}
pub fn insert(&mut self, file_id: FileId, input: FileInput) {
self.entries.insert(file_id, input);
}
pub fn remove(&mut self, file_id: FileId) -> Option<FileInput> {
self.entries.remove(&file_id)
}
#[inline]
#[must_use]
pub fn file_count(&self) -> usize {
self.entries.len()
}
pub fn file_ids(&self) -> impl Iterator<Item = FileId> + '_ {
self.entries.keys().copied()
}
pub fn iter(&self) -> impl Iterator<Item = (FileId, &FileInput)> + '_ {
self.entries.iter().map(|(&fid, fi)| (fid, fi))
}
#[must_use]
pub fn all_revisions(&self) -> Vec<(FileId, u64)> {
self.entries
.iter()
.map(|(&fid, fi)| (fid, fi.revision))
.collect()
}
pub(crate) fn restore_revisions(&mut self, revisions: &[(FileId, u64)]) {
for &(fid, saved_rev) in revisions {
match self.entries.get_mut(&fid) {
Some(fi) => {
fi.revision = saved_rev;
}
None => {
let mut fi = FileInput::new(smallvec::SmallVec::new());
fi.revision = saved_rev;
self.entries.insert(fid, fi);
}
}
}
}
}
impl Default for FileInputStore {
fn default() -> Self {
Self::new()
}
}