active.rs 3.83 KB
Newer Older
Ryan Olson's avatar
Ryan Olson committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

Ryan Olson's avatar
Ryan Olson committed
16
17
use crate::block_manager::block::locality::LocalityProvider;

Ryan Olson's avatar
Ryan Olson committed
18
19
20
use super::*;

/// Manages active blocks being used by sequences
Ryan Olson's avatar
Ryan Olson committed
21
22
23
24
25
26
27
28
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
29
30
}

Ryan Olson's avatar
Ryan Olson committed
31
impl<S: Storage, L: LocalityProvider, M: BlockMetadata> ActiveBlockPool<S, L, M> {
Ryan Olson's avatar
Ryan Olson committed
32
33
34
35
36
37
38
39
    pub fn new() -> Self {
        Self {
            map: HashMap::new(),
        }
    }

    pub fn register(
        &mut self,
Ryan Olson's avatar
Ryan Olson committed
40
41
        mut block: MutableBlock<S, L, M>,
    ) -> Result<ImmutableBlock<S, L, M>, BlockPoolError> {
Ryan Olson's avatar
Ryan Olson committed
42
43
44
45
46
47
48
49
50
51
        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())
        })?;

52
53
54
55
56
57
58
59
        // 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.
        if let Ok(Some(parent)) = block.parent_sequence_hash() {
            if let Some(parent_block) = self.match_sequence_hash(parent) {
                block.set_parent(parent_block.mutable_block().clone());
            }
        }

Ryan Olson's avatar
Ryan Olson committed
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
        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
80
    pub fn remove(&mut self, block: &mut Block<S, L, M>) {
Ryan Olson's avatar
Ryan Olson committed
81
82
83
84
85
86
87
88
89
90
91
92
93
94
        if let Ok(sequence_hash) = block.sequence_hash() {
            if let Some(weak) = self.map.get(&sequence_hash) {
                if let Some(_arc) = weak.upgrade() {
                    block.reset();
                    return;
                }
                self.map.remove(&sequence_hash);
            }
        }
    }

    pub fn match_sequence_hash(
        &mut self,
        sequence_hash: SequenceHash,
Ryan Olson's avatar
Ryan Olson committed
95
    ) -> Option<ImmutableBlock<S, L, M>> {
Ryan Olson's avatar
Ryan Olson committed
96
97
98
99
100
101
102
103
104
105
106
107
        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
108
109
110
111

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