j2k_core/context.rs
1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3/// Cache hit/miss counters reported by codec contexts.
4#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
5pub struct CacheStats {
6 /// Number of cache lookups that reused existing state.
7 pub hits: u64,
8 /// Number of cache lookups that had to build new state.
9 pub misses: u64,
10 /// Number of currently occupied cache slots.
11 pub occupied_slots: u64,
12 /// Number of cache entries evicted by later insertions.
13 pub evictions: u64,
14}
15
16impl CacheStats {
17 /// Construct cache statistics from explicit counters.
18 #[must_use]
19 pub const fn new(hits: u64, misses: u64) -> Self {
20 Self {
21 hits,
22 misses,
23 occupied_slots: 0,
24 evictions: 0,
25 }
26 }
27
28 /// Construct cache statistics from full counters.
29 #[must_use]
30 pub const fn with_slots(hits: u64, misses: u64, occupied_slots: u64, evictions: u64) -> Self {
31 Self {
32 hits,
33 misses,
34 occupied_slots,
35 evictions,
36 }
37 }
38}
39
40/// Reusable codec state cached across decode calls.
41pub trait CodecContext: Default + Send {
42 /// Drop cached state while keeping the context reusable.
43 fn clear(&mut self);
44
45 /// Return current cache counters, when the codec tracks them.
46 fn cache_stats(&self) -> CacheStats {
47 CacheStats::default()
48 }
49}
50
51/// Wrapper that owns codec context state for repeated decode calls.
52#[derive(Debug, Default)]
53pub struct DecoderContext<C: CodecContext> {
54 codec: C,
55}
56
57impl<C: CodecContext> DecoderContext<C> {
58 /// Construct an empty decoder context.
59 #[must_use]
60 pub fn new() -> Self {
61 Self {
62 codec: C::default(),
63 }
64 }
65
66 /// Borrow the codec-specific context.
67 pub fn codec(&self) -> &C {
68 &self.codec
69 }
70
71 /// Mutably borrow the codec-specific context.
72 pub fn codec_mut(&mut self) -> &mut C {
73 &mut self.codec
74 }
75
76 /// Clear cached codec state.
77 pub fn clear(&mut self) {
78 self.codec.clear();
79 }
80
81 /// Return cache counters from the codec-specific context.
82 pub fn cache_stats(&self) -> CacheStats {
83 self.codec.cache_stats()
84 }
85
86 /// Consume the wrapper and return the codec-specific context.
87 pub fn into_inner(self) -> C {
88 self.codec
89 }
90}
91
92#[cfg(test)]
93mod tests;