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}