inference_lab/kv_cache/
block.rs1use crate::request::BlockId;
2
3#[derive(Debug, Clone)]
5pub struct Block {
6 pub block_id: BlockId,
8
9 pub ref_count: u32,
11
12 pub is_free: bool,
14
15 pub content_hash: Option<u64>,
17}
18
19impl Block {
20 pub fn new(block_id: BlockId) -> Self {
22 Self {
23 block_id,
24 ref_count: 0,
25 is_free: true,
26 content_hash: None,
27 }
28 }
29
30 pub fn allocate(&mut self, content_hash: Option<u64>) -> Option<u64> {
32 self.ref_count += 1;
33 self.is_free = false;
34 std::mem::replace(&mut self.content_hash, content_hash)
35 }
36
37 pub fn release(&mut self) {
39 if self.ref_count > 0 {
40 self.ref_count -= 1;
41 }
42
43 if self.ref_count == 0 {
44 self.is_free = true;
46 }
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn test_block_creation() {
56 let block = Block::new(0);
57 assert_eq!(block.block_id, 0);
58 assert_eq!(block.ref_count, 0);
59 assert!(block.is_free);
60 assert!(block.content_hash.is_none());
61 }
62
63 #[test]
64 fn test_block_allocate() {
65 let mut block = Block::new(0);
66
67 block.allocate(None);
68 assert_eq!(block.ref_count, 1);
69 assert!(!block.is_free);
70
71 block.allocate(None);
72 assert_eq!(block.ref_count, 2);
73 assert!(!block.is_free);
74 }
75
76 #[test]
77 fn test_block_release() {
78 let mut block = Block::new(0);
79 block.allocate(None);
80 block.allocate(None);
81
82 block.release();
83 assert_eq!(block.ref_count, 1);
84 assert!(!block.is_free);
85
86 block.release();
87 assert_eq!(block.ref_count, 0);
88 assert!(block.is_free);
89
90 block.release();
92 assert_eq!(block.ref_count, 0);
93 assert!(block.is_free);
94 }
95}