Skip to main content

nydus_storage/cache/state/
digested_chunk_map.rs

1// Copyright 2021 Ant Group. All rights reserved.
2// Copyright (C) 2021 Alibaba Cloud. All rights reserved.
3//
4// SPDX-License-Identifier: Apache-2.0
5
6//! A chunk state tracking driver for legacy Nydus images without chunk array
7//!
8//! This module provides a chunk state tracking driver for legacy Rafs images without chunk array,
9//! which uses chunk digest as id to track chunk readiness state. The [DigestedChunkMap] is not
10//! optimal in case of performance and memory consumption. So it is only used to keep backward
11/// compatibility with the old nydus image format.
12use std::collections::HashSet;
13use std::io::Result;
14use std::sync::RwLock;
15
16use nydus_utils::digest::RafsDigest;
17
18use crate::cache::state::{ChunkIndexGetter, ChunkMap};
19use crate::device::BlobChunkInfo;
20
21/// An implementation of [ChunkMap](trait.ChunkMap.html) to support chunk state tracking by using
22/// `HashSet<RafsDigest>`.
23///
24/// The `DigestedChunkMap` is an implementation of [ChunkMap] which uses a hash set
25/// (HashSet<chunk_digest>) to record whether a chunk has already been cached by the blob cache.
26/// The implementation is memory and computation heavy, so it is used only to keep backward
27/// compatibility with the previous old nydus bootstrap format. For new clients, please use other
28/// alternative implementations.
29#[derive(Default)]
30pub struct DigestedChunkMap {
31    cache: RwLock<HashSet<RafsDigest>>,
32}
33
34impl DigestedChunkMap {
35    /// Create a new instance of `DigestedChunkMap`.
36    pub fn new() -> Self {
37        Self {
38            cache: RwLock::new(HashSet::new()),
39        }
40    }
41}
42
43impl ChunkMap for DigestedChunkMap {
44    fn is_ready(&self, chunk: &dyn BlobChunkInfo) -> Result<bool> {
45        Ok(self.cache.read().unwrap().contains(chunk.chunk_id()))
46    }
47
48    fn set_ready_and_clear_pending(&self, chunk: &dyn BlobChunkInfo) -> Result<()> {
49        // Do not expect poisoned lock.
50        self.cache.write().unwrap().insert(*chunk.chunk_id());
51        Ok(())
52    }
53}
54
55impl ChunkIndexGetter for DigestedChunkMap {
56    type Index = RafsDigest;
57
58    fn get_index(chunk: &dyn BlobChunkInfo) -> Self::Index {
59        *chunk.chunk_id()
60    }
61}