GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/ingestion/item.cc
Date: 2026-10-25 02:40:14
Exec Total Coverage
Lines: 143 143 100.0%
Branches: 34 62 54.8%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #include "item.h"
6
7 #include <algorithm>
8 #include <cassert>
9 #include <cstdlib>
10 #include <cstring>
11
12 #include "ingestion/ingestion_source.h"
13 #include "item_mem.h"
14 #include "util/concurrency.h"
15 #include "util/smalloc.h"
16
17 8370023 FileItem::FileItem(IngestionSource *source,
18 uint64_t min_chunk_size,
19 uint64_t avg_chunk_size,
20 uint64_t max_chunk_size,
21 zlib::Algorithms compression_algorithm,
22 shash::Algorithms hash_algorithm,
23 shash::Suffix hash_suffix,
24 bool may_have_chunks,
25 8370023 bool has_legacy_bulk_chunk)
26 8370023 : source_(source)
27 8370023 , compression_algorithm_(compression_algorithm)
28 8370023 , hash_algorithm_(hash_algorithm)
29 8370023 , hash_suffix_(hash_suffix)
30 8370023 , has_legacy_bulk_chunk_(has_legacy_bulk_chunk)
31 8370023 , size_(kSizeUnknown)
32 8370023 , may_have_chunks_(may_have_chunks)
33
1/2
✓ Branch 1 taken 8370023 times.
✗ Branch 2 not taken.
8370023 , chunk_detector_(min_chunk_size, avg_chunk_size, max_chunk_size)
34
1/2
✓ Branch 1 taken 8370023 times.
✗ Branch 2 not taken.
8370023 , bulk_hash_(hash_algorithm)
35
1/2
✓ Branch 1 taken 8370023 times.
✗ Branch 2 not taken.
8370023 , chunks_(1) {
36 8370023 const int retval = pthread_mutex_init(&lock_, NULL);
37
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8370023 times.
8370023 assert(retval == 0);
38 8370023 nchunks_in_fly_.store(0);
39 8370023 is_fully_chunked_.store(0);
40 8370023 }
41
42 8364835 FileItem::~FileItem() { pthread_mutex_destroy(&lock_); }
43
44 8267591 void FileItem::RegisterChunk(const FileChunk &file_chunk) {
45 8267591 const MutexLockGuard lock_guard(lock_);
46
47
2/2
✓ Branch 1 taken 15033 times.
✓ Branch 2 taken 8252558 times.
8267591 switch (file_chunk.content_hash().suffix) {
48 15033 case shash::kSuffixPartial:
49
1/2
✓ Branch 1 taken 15033 times.
✗ Branch 2 not taken.
15033 chunks_.PushBack(file_chunk);
50 15033 break;
51
52 8252558 default:
53
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8252558 times.
8252558 assert(file_chunk.offset() == 0);
54
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8252558 times.
8252558 assert(file_chunk.size() == size_);
55 8252558 bulk_hash_ = file_chunk.content_hash();
56 8252558 break;
57 }
58 8267591 nchunks_in_fly_.fetch_sub(1);
59 8267591 }
60
61
62 //------------------------------------------------------------------------------
63
64
65 8502047 ChunkItem::ChunkItem(FileItem *file_item, uint64_t offset)
66 8502047 : file_item_(file_item)
67 8502047 , offset_(offset)
68 8502047 , size_(0)
69 8502047 , is_bulk_chunk_(false)
70 8502047 , upload_handle_(NULL)
71
1/2
✓ Branch 3 taken 8502872 times.
✗ Branch 4 not taken.
8502047 , compressor_(nullptr) {
72 8502872 hash_ctx_.algorithm = file_item->hash_algorithm();
73
1/2
✓ Branch 1 taken 8500364 times.
✗ Branch 2 not taken.
8501288 hash_ctx_.size = shash::GetContextSize(hash_ctx_.algorithm);
74 8500364 hash_ctx_.buffer = hash_ctx_buffer_;
75
1/2
✓ Branch 1 taken 8498186 times.
✗ Branch 2 not taken.
8500364 shash::Init(hash_ctx_);
76 8498186 hash_value_.algorithm = hash_ctx_.algorithm;
77 8498186 hash_value_.suffix = shash::kSuffixPartial;
78 8498186 file_item_->IncNchunksInFly();
79 8506139 }
80
81
82 8243264 void ChunkItem::MakeBulkChunk() {
83 8243264 is_bulk_chunk_ = true;
84 8243264 hash_value_.suffix = file_item_->hash_suffix();
85 8241845 }
86
87
88 19217851 zlib::Compressor *ChunkItem::GetCompressor() {
89
2/2
✓ Branch 1 taken 8259899 times.
✓ Branch 2 taken 10960625 times.
19217851 if (compressor_.get() == nullptr) {
90 16525573 compressor_ = std::unique_ptr<zlib::Compressor>(
91
1/2
✓ Branch 2 taken 8263463 times.
✗ Branch 3 not taken.
24783855 zlib::Compressor::Construct(file_item_->compression_algorithm()));
92 }
93 19221844 return compressor_.get();
94 }
95
96
97 8263034 void ChunkItem::ReleaseCompressor() { compressor_.reset(); }
98
99
100 //------------------------------------------------------------------------------
101
102 std::atomic<int64_t> BlockItem::managed_bytes_(0);
103
104
105 181952 BlockItem::BlockItem(ItemAllocator *allocator)
106 181952 : allocator_(allocator)
107 181952 , type_(kBlockHollow)
108 181952 , tag_(-1)
109 181952 , file_item_(NULL)
110 181952 , chunk_item_(NULL)
111 181952 , data_(NULL)
112 181952 , capacity_(0)
113 181952 , size_(0) { }
114
115
116 61448088 BlockItem::BlockItem(int64_t tag, ItemAllocator *allocator)
117 61448088 : allocator_(allocator)
118 61448088 , type_(kBlockHollow)
119 61448088 , tag_(tag)
120 61448088 , file_item_(NULL)
121 61448088 , chunk_item_(NULL)
122 61448088 , data_(NULL)
123 61448088 , capacity_(0)
124 61448088 , size_(0) {
125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61448088 times.
61448088 assert(tag_ >= 0);
126 61448088 }
127
128
129 61638862 BlockItem::~BlockItem() {
130
2/2
✓ Branch 0 taken 26075776 times.
✓ Branch 1 taken 35563086 times.
61638862 if (data_)
131 26075776 allocator_->Free(data_);
132 61659651 managed_bytes_.fetch_add(-static_cast<int64_t>(capacity_));
133 61659651 }
134
135
136 9100358 void BlockItem::Discharge() {
137 9100358 data_ = NULL;
138 9100358 size_ = capacity_ = 0;
139 9100358 }
140
141
142 25000926 void BlockItem::MakeStop() {
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25000926 times.
25000926 assert(type_ == kBlockHollow);
144 25000926 type_ = kBlockStop;
145 25000926 }
146
147
148 12815054 void BlockItem::MakeData(uint32_t capacity) {
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12815054 times.
12815054 assert(type_ == kBlockHollow);
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12815054 times.
12815054 assert(allocator_ != NULL);
151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12815054 times.
12815054 assert(capacity > 0);
152
153 12815054 type_ = kBlockData;
154 12815054 capacity_ = capacity;
155 12815054 data_ = reinterpret_cast<unsigned char *>(allocator_->Malloc(capacity_));
156 12822083 managed_bytes_.fetch_add(static_cast<int64_t>(capacity_));
157 12822083 }
158
159
160 /**
161 * Move data from one block to another.
162 */
163 9102602 void BlockItem::MakeDataMove(BlockItem *other) {
164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9102602 times.
9102602 assert(type_ == kBlockHollow);
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9102602 times.
9102602 assert(other->type_ == kBlockData);
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9102602 times.
9102602 assert(other->size_ > 0);
167
168 9102602 type_ = kBlockData;
169 9102602 capacity_ = size_ = other->size_;
170 9102602 data_ = other->data_;
171 9102602 allocator_ = other->allocator_;
172
173 9102602 other->Discharge();
174 9101546 }
175
176
177 /**
178 * Copy a piece of one block's data into a new block.
179 */
180 14616599 void BlockItem::MakeDataCopy(const unsigned char *data, uint32_t size) {
181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14616599 times.
14616599 assert(type_ == kBlockHollow);
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14616599 times.
14616599 assert(allocator_ != NULL);
183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14616599 times.
14616599 assert(size > 0);
184
185 14616599 type_ = kBlockData;
186 14616599 capacity_ = size_ = size;
187 14616599 data_ = reinterpret_cast<unsigned char *>(allocator_->Malloc(capacity_));
188 14640584 memcpy(data_, data, size);
189 14640584 managed_bytes_.fetch_add(static_cast<int64_t>(capacity_));
190 14640584 }
191
192
193 1384407 void BlockItem::Reset() {
194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1384407 times.
1384407 assert(type_ == kBlockData);
195
196 1384407 managed_bytes_.fetch_add(-static_cast<int64_t>(capacity_));
197 1384407 allocator_->Free(data_);
198 1384704 data_ = NULL;
199 1384704 size_ = capacity_ = 0;
200 1384704 type_ = kBlockHollow;
201 1384704 }
202
203
204 42708857 void BlockItem::SetChunkItem(ChunkItem *value) {
205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42708857 times.
42708857 assert(value != NULL);
206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42708857 times.
42708857 assert(chunk_item_ == NULL);
207 42708857 chunk_item_ = value;
208 42708857 }
209
210
211 61394727 void BlockItem::SetFileItem(FileItem *value) {
212
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61394727 times.
61394727 assert(value != NULL);
213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 61394727 times.
61394727 assert(file_item_ == NULL);
214 61394727 file_item_ = value;
215 61394727 }
216
217
218 24576 uint32_t BlockItem::Write(void *buf, uint32_t count) {
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24576 times.
24576 assert(type_ == kBlockData);
220
221 24576 const uint32_t remaining = capacity_ - size_;
222 24576 const uint32_t nbytes = std::min(remaining, count);
223 24576 memcpy(data_ + size_, buf, nbytes);
224 24576 size_ += nbytes;
225 24576 return nbytes;
226 }
227
228