Skip to main content

oxihuman_core/
cache_line.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3#![allow(dead_code)]
4
5/// Represents a single cache line with key, value, and metadata.
6#[allow(dead_code)]
7#[derive(Debug, Clone)]
8pub struct CacheLine {
9    key: String,
10    data: Vec<u8>,
11    access_count: u64,
12    dirty: bool,
13    valid: bool,
14}
15
16#[allow(dead_code)]
17impl CacheLine {
18    pub fn new(key: &str, data: Vec<u8>) -> Self {
19        Self {
20            key: key.to_string(),
21            data,
22            access_count: 0,
23            dirty: false,
24            valid: true,
25        }
26    }
27
28    pub fn invalid() -> Self {
29        Self {
30            key: String::new(),
31            data: Vec::new(),
32            access_count: 0,
33            dirty: false,
34            valid: false,
35        }
36    }
37
38    pub fn key(&self) -> &str {
39        &self.key
40    }
41
42    pub fn data(&self) -> &[u8] {
43        &self.data
44    }
45
46    pub fn access(&mut self) -> &[u8] {
47        self.access_count += 1;
48        &self.data
49    }
50
51    pub fn write(&mut self, data: Vec<u8>) {
52        self.data = data;
53        self.dirty = true;
54        self.access_count += 1;
55    }
56
57    pub fn is_dirty(&self) -> bool {
58        self.dirty
59    }
60
61    pub fn is_valid(&self) -> bool {
62        self.valid
63    }
64
65    pub fn invalidate(&mut self) {
66        self.valid = false;
67    }
68
69    pub fn access_count(&self) -> u64 {
70        self.access_count
71    }
72
73    pub fn size(&self) -> usize {
74        self.data.len()
75    }
76
77    pub fn mark_clean(&mut self) {
78        self.dirty = false;
79    }
80
81    pub fn matches_key(&self, key: &str) -> bool {
82        self.valid && self.key == key
83    }
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn test_new() {
92        let cl = CacheLine::new("key1", vec![1, 2, 3]);
93        assert_eq!(cl.key(), "key1");
94        assert_eq!(cl.data(), &[1, 2, 3]);
95        assert!(cl.is_valid());
96        assert!(!cl.is_dirty());
97    }
98
99    #[test]
100    fn test_invalid() {
101        let cl = CacheLine::invalid();
102        assert!(!cl.is_valid());
103    }
104
105    #[test]
106    fn test_access_increments_count() {
107        let mut cl = CacheLine::new("k", vec![10]);
108        assert_eq!(cl.access_count(), 0);
109        let _ = cl.access();
110        assert_eq!(cl.access_count(), 1);
111    }
112
113    #[test]
114    fn test_write_marks_dirty() {
115        let mut cl = CacheLine::new("k", vec![]);
116        cl.write(vec![5, 6]);
117        assert!(cl.is_dirty());
118        assert_eq!(cl.data(), &[5, 6]);
119    }
120
121    #[test]
122    fn test_invalidate() {
123        let mut cl = CacheLine::new("k", vec![1]);
124        cl.invalidate();
125        assert!(!cl.is_valid());
126    }
127
128    #[test]
129    fn test_size() {
130        let cl = CacheLine::new("k", vec![0; 100]);
131        assert_eq!(cl.size(), 100);
132    }
133
134    #[test]
135    fn test_mark_clean() {
136        let mut cl = CacheLine::new("k", vec![]);
137        cl.write(vec![1]);
138        cl.mark_clean();
139        assert!(!cl.is_dirty());
140    }
141
142    #[test]
143    fn test_matches_key() {
144        let cl = CacheLine::new("abc", vec![]);
145        assert!(cl.matches_key("abc"));
146        assert!(!cl.matches_key("xyz"));
147    }
148
149    #[test]
150    fn test_matches_key_invalid() {
151        let mut cl = CacheLine::new("abc", vec![]);
152        cl.invalidate();
153        assert!(!cl.matches_key("abc"));
154    }
155
156    #[test]
157    fn test_write_increments_access() {
158        let mut cl = CacheLine::new("k", vec![]);
159        cl.write(vec![1]);
160        cl.write(vec![2]);
161        assert_eq!(cl.access_count(), 2);
162    }
163}