mzdata/io/
offset_index.rs

1#[allow(unused)]
2use std::io::prelude::*;
3
4use indexmap::map::{Iter, Keys};
5use indexmap::IndexMap;
6
7
8/**
9An ordered mapping from entity ID to byte offset into the source
10file it resides in.
11
12A wrapper around [`indexmap::IndexMap`].
13*/
14#[derive(Default, Debug, Clone)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub struct OffsetIndex {
17    /// The name of the index. There may potentially be more than one
18    /// index per file
19    pub name: String,
20
21    /// The mapping from ID to byte offset, ordered by occurrence
22    // If using serde_json to save this, use
23    #[cfg_attr(feature = "serde", serde(with = "indexmap::map::serde_seq"))]
24    pub offsets: IndexMap<Box<str>, u64>,
25
26    /// Whether the index has been initalized explicitly or not, as
27    /// it may be initially empty or read as empty.
28    pub init: bool,
29}
30
31impl OffsetIndex {
32    pub fn new(name: String) -> OffsetIndex {
33        OffsetIndex {
34            name,
35            ..Default::default()
36        }
37    }
38
39    /// Get the offset of the specified key
40    #[inline]
41    pub fn get(&self, key: &str) -> Option<u64> {
42        self.offsets.get(key).copied()
43    }
44
45    /// Get the associated key and offset for the specified index position
46    #[inline]
47    pub fn get_index(&self, index: usize) -> Option<(&str, u64)> {
48        if let Some((key, offset)) = self.offsets.get_index(index) {
49            Some((key, *offset))
50        } else {
51            None
52        }
53    }
54
55    /// Get the position in the index for a specific key
56    #[inline]
57    pub fn index_of(&self, key: &str) -> Option<usize> {
58        self.offsets.get_index_of(key)
59    }
60
61    /// Insert `key` into the index with an offset value
62    #[inline]
63    pub fn insert<T: Into<Box<str>>>(&mut self, key: T, offset: u64) -> Option<u64> {
64        self.offsets.insert(key.into(), offset)
65    }
66
67    #[inline]
68    pub fn len(&self) -> usize {
69        self.offsets.len()
70    }
71
72    pub fn is_empty(&self) -> bool {
73        self.offsets.is_empty()
74    }
75
76    pub fn keys(&self) -> Keys<Box<str>, u64> {
77        self.offsets.keys()
78    }
79
80    /// Iterate over the keys and indices
81    pub fn iter(&self) -> Iter<Box<str>, u64> {
82        self.offsets.iter()
83    }
84
85    /// Check if the key is in the index
86    #[inline]
87    pub fn contains_key(&self, key: &str) -> bool {
88        self.offsets.contains_key(key)
89    }
90
91    #[cfg(feature = "serde")]
92    /// Write the index out in JSON format to `writer`
93    pub fn to_writer<W: Write>(&self, writer: W) -> serde_json::Result<()> {
94        serde_json::to_writer(writer, self)
95    }
96
97    #[cfg(feature = "serde")]
98    /// Read an index in JSON format from `reader`
99    pub fn from_reader<R: Read>(reader: R) -> serde_json::Result<Self> {
100        serde_json::from_reader(reader)
101    }
102}