active.rs 3.25 KB
Newer Older
Ryan Olson's avatar
Ryan Olson committed
1
2
3
// SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

Ryan Olson's avatar
Ryan Olson committed
4
5
use crate::block_manager::block::locality::LocalityProvider;

Ryan Olson's avatar
Ryan Olson committed
6
7
8
use super::*;

/// Manages active blocks being used by sequences
Ryan Olson's avatar
Ryan Olson committed
9
10
11
12
13
14
15
16
pub struct ActiveBlockPool<S: Storage, L: LocalityProvider, M: BlockMetadata> {
    pub(super) map: HashMap<SequenceHash, Weak<MutableBlock<S, L, M>>>,
}

impl<S: Storage, L: LocalityProvider, M: BlockMetadata> Default for ActiveBlockPool<S, L, M> {
    fn default() -> Self {
        Self::new()
    }
Ryan Olson's avatar
Ryan Olson committed
17
18
}

Ryan Olson's avatar
Ryan Olson committed
19
impl<S: Storage, L: LocalityProvider, M: BlockMetadata> ActiveBlockPool<S, L, M> {
Ryan Olson's avatar
Ryan Olson committed
20
21
22
23
24
25
26
27
    pub fn new() -> Self {
        Self {
            map: HashMap::new(),
        }
    }

    pub fn register(
        &mut self,
Ryan Olson's avatar
Ryan Olson committed
28
29
        mut block: MutableBlock<S, L, M>,
    ) -> Result<ImmutableBlock<S, L, M>, BlockPoolError> {
Ryan Olson's avatar
Ryan Olson committed
30
31
32
33
34
35
36
37
38
39
        if !block.state().is_registered() {
            return Err(BlockPoolError::InvalidMutableBlock(
                "block is not registered".to_string(),
            ));
        }

        let sequence_hash = block.sequence_hash().map_err(|_| {
            BlockPoolError::InvalidMutableBlock("block has no sequence hash".to_string())
        })?;

40
41
        // Set the parent of the block if it has one.
        // This is needed to ensure the lifetime of the parent is at least as long as the child.
42
43
44
45
        if let Ok(Some(parent)) = block.parent_sequence_hash()
            && let Some(parent_block) = self.match_sequence_hash(parent)
        {
            block.set_parent(parent_block.mutable_block().clone());
46
47
        }

Ryan Olson's avatar
Ryan Olson committed
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
        let shared = Arc::new(block);

        match self.map.entry(sequence_hash) {
            std::collections::hash_map::Entry::Occupied(mut entry) => {
                let weak = entry.get();
                if let Some(arc) = weak.upgrade() {
                    Ok(ImmutableBlock::new(arc))
                } else {
                    // Weak reference is no longer alive, update it in the map
                    entry.insert(Arc::downgrade(&shared));
                    Ok(ImmutableBlock::new(shared))
                }
            }
            std::collections::hash_map::Entry::Vacant(entry) => {
                entry.insert(Arc::downgrade(&shared));
                Ok(ImmutableBlock::new(shared))
            }
        }
    }

Ryan Olson's avatar
Ryan Olson committed
68
    pub fn remove(&mut self, block: &mut Block<S, L, M>) {
69
70
71
72
73
74
        if let Ok(sequence_hash) = block.sequence_hash()
            && let Some(weak) = self.map.get(&sequence_hash)
        {
            if let Some(_arc) = weak.upgrade() {
                block.reset();
                return;
Ryan Olson's avatar
Ryan Olson committed
75
            }
76
            self.map.remove(&sequence_hash);
Ryan Olson's avatar
Ryan Olson committed
77
78
79
80
81
82
        }
    }

    pub fn match_sequence_hash(
        &mut self,
        sequence_hash: SequenceHash,
Ryan Olson's avatar
Ryan Olson committed
83
    ) -> Option<ImmutableBlock<S, L, M>> {
Ryan Olson's avatar
Ryan Olson committed
84
85
86
87
88
89
90
91
92
93
94
95
        if let Some(weak) = self.map.get(&sequence_hash) {
            if let Some(arc) = weak.upgrade() {
                Some(ImmutableBlock::new(arc))
            } else {
                // Weak reference is no longer alive, remove it from the map
                self.map.remove(&sequence_hash);
                None
            }
        } else {
            None
        }
    }
Ryan Olson's avatar
Ryan Olson committed
96
97
98
99

    pub fn status(&self) -> usize {
        self.map.keys().len()
    }
Ryan Olson's avatar
Ryan Olson committed
100
}