commonlibsse_ng\rel\id/offset_to_id.rs
1// C++ Original code
2// - https://github.com/SARDONYX-forks/CommonLibVR/blob/ng/include/REL/ID.h
3// - https://github.com/SARDONYX-forks/CommonLibVR/blob/ng/src/REL/ID.cpp
4// SPDX-FileCopyrightText: (C) 2018 Ryan-rsm-McKenzie
5// SPDX-License-Identifier: MIT
6
7//! Provides functionality to map offsets to unique IDs using a sorted mapping.
8//!
9//! This module allows efficient lookup of IDs corresponding to memory offsets.
10//! The mapping is backed by a sorted vector for quick binary search.
11
12use super::Mapping;
13use super::id_database::ID_DATABASE;
14use shared_rwlock::{PoisonError, RwLockReadGuard};
15
16#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
17/// Maps memory offsets to unique IDs using a sorted list for quick lookup.
18pub struct OffsetToID {
19 /// Parses bin data from `AddressLibrary` and arranges offset/id pair structures in order of offset.
20 offset_to_id: Vec<Mapping>,
21}
22
23// FIXME: This side effect is not testable.
24impl OffsetToID {
25 /// Creates a new `Offset2ID` instance by loading the offset-to-ID mapping(Global instance).
26 ///
27 /// # Errors
28 /// If poisoned.
29 ///
30 /// # Note
31 /// Parse the binary table of bin data in `AddressLibrary` and arrange the offset/id pair structures in order of offset,
32 /// noting that a call to [`Clone::clone`] is made to prevent sort from destroying the existing table.
33 pub fn new() -> Result<Self, PoisonError<RwLockReadGuard<'static, Mapping>>> {
34 let mut offset_to_id = ID_DATABASE.mem_map.read()?.to_vec();
35 offset_to_id.sort_by(|a, b| a.offset.cmp(&b.offset));
36 Ok(Self { offset_to_id })
37 }
38
39 /// Gets the ID corresponding to the given `offset`, if available.
40 ///
41 /// Performs a binary search on the sorted mapping. O(log n)
42 pub fn get_id(&self, offset: u64) -> Option<u64> {
43 let elem = Mapping { id: 0, offset };
44 self.offset_to_id
45 .binary_search_by(|m| m.offset.cmp(&elem.offset))
46 .ok()
47 .map(|index| self.offset_to_id[index].id)
48 }
49}