GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/ingestion/item.cc Lines: 109 109 100.0 %
Date: 2019-02-03 02:48:13 Branches: 27 50 54.0 %

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 "smalloc.h"
15
#include "util_concurrency.h"
16
17
958
FileItem::FileItem(
18
  IngestionSource* source,
19
  uint64_t min_chunk_size,
20
  uint64_t avg_chunk_size,
21
  uint64_t max_chunk_size,
22
  zlib::Algorithms compression_algorithm,
23
  shash::Algorithms hash_algorithm,
24
  shash::Suffix hash_suffix,
25
  bool may_have_chunks,
26
  bool has_legacy_bulk_chunk)
27
  : source_(source)
28
  , compression_algorithm_(compression_algorithm)
29
  , hash_algorithm_(hash_algorithm)
30
  , hash_suffix_(hash_suffix)
31
  , has_legacy_bulk_chunk_(has_legacy_bulk_chunk)
32
  , size_(kSizeUnknown)
33
  , may_have_chunks_(may_have_chunks)
34
  , chunk_detector_(min_chunk_size, avg_chunk_size, max_chunk_size)
35
  , bulk_hash_(hash_algorithm)
36
958
  , chunks_(1)
37
{
38
958
  int retval = pthread_mutex_init(&lock_, NULL);
39
958
  assert(retval == 0);
40
958
  atomic_init64(&nchunks_in_fly_);
41
958
  atomic_init32(&is_fully_chunked_);
42
958
}
43
44
958
FileItem::~FileItem() {
45
958
  pthread_mutex_destroy(&lock_);
46
958
}
47
48
1814
void FileItem::RegisterChunk(const FileChunk &file_chunk) {
49
1814
  MutexLockGuard lock_guard(lock_);
50
51
1814
  switch (file_chunk.content_hash().suffix) {
52
    case shash::kSuffixPartial:
53
1668
      chunks_.PushBack(file_chunk);
54
1668
      break;
55
56
    default:
57
146
      assert(file_chunk.offset() == 0);
58
146
      assert(file_chunk.size() == size_);
59
146
      bulk_hash_ = file_chunk.content_hash();
60
      break;
61
  }
62
1814
  atomic_dec64(&nchunks_in_fly_);
63
1814
}
64
65
66
//------------------------------------------------------------------------------
67
68
69
6825
ChunkItem::ChunkItem(FileItem *file_item, uint64_t offset)
70
  : file_item_(file_item)
71
  , offset_(offset)
72
  , size_(0)
73
  , is_bulk_chunk_(false)
74
  , upload_handle_(NULL)
75
6825
  , compressor_(zlib::Compressor::Construct(file_item->compression_algorithm()))
76
{
77
6825
  hash_ctx_.algorithm = file_item->hash_algorithm();
78
6825
  hash_ctx_.size = shash::GetContextSize(hash_ctx_.algorithm);
79
6825
  hash_ctx_buffer_ = smalloc(hash_ctx_.size);
80
6825
  hash_ctx_.buffer = hash_ctx_buffer_;
81
6825
  shash::Init(hash_ctx_);
82
6825
  hash_value_.algorithm = hash_ctx_.algorithm;
83
6825
  hash_value_.suffix = shash::kSuffixPartial;
84
6825
  file_item_->IncNchunksInFly();
85
}
86
87
88
149
void ChunkItem::MakeBulkChunk() {
89
149
  is_bulk_chunk_ = true;
90
149
  hash_value_.suffix = file_item_->hash_suffix();
91
149
}
92
93
94
//------------------------------------------------------------------------------
95
96
atomic_int64 BlockItem::managed_bytes_ = 0;
97
98
99
2356
BlockItem::BlockItem(ItemAllocator *allocator)
100
  : allocator_(allocator)
101
  , type_(kBlockHollow)
102
  , tag_(-1)
103
  , file_item_(NULL)
104
  , chunk_item_(NULL)
105
  , data_(NULL)
106
  , capacity_(0)
107
2356
  , size_(0)
108
2356
{ }
109
110
111
1153503
BlockItem::BlockItem(int64_t tag, ItemAllocator *allocator)
112
  : allocator_(allocator)
113
  , type_(kBlockHollow)
114
  , tag_(tag)
115
  , file_item_(NULL)
116
  , chunk_item_(NULL)
117
  , data_(NULL)
118
  , capacity_(0)
119
1153503
  , size_(0)
120
{
121
1153569
  assert(tag_ >= 0);
122
1153569
}
123
124
125
1156008
BlockItem::~BlockItem() {
126
1156008
  if (data_)
127
920350
    allocator_->Free(data_);
128
1156036
  atomic_xadd64(&managed_bytes_, -static_cast<int64_t>(capacity_));
129
1156093
}
130
131
132
106655
void BlockItem::Discharge() {
133
106655
  data_ = NULL;
134
106655
  size_ = capacity_ = 0;
135
106655
}
136
137
138
8768
void BlockItem::MakeStop() {
139
8768
  assert(type_ == kBlockHollow);
140
8768
  type_ = kBlockStop;
141
8768
}
142
143
144
545922
void BlockItem::MakeData(uint32_t capacity) {
145
545922
  assert(type_ == kBlockHollow);
146
545922
  assert(allocator_ != NULL);
147
545922
  assert(capacity > 0);
148
149
545922
  type_ = kBlockData;
150
545922
  capacity_ = capacity;
151
545922
  data_ = reinterpret_cast<unsigned char *>(allocator_->Malloc(capacity_));
152
545922
  atomic_xadd64(&managed_bytes_, static_cast<int64_t>(capacity_));
153
545922
}
154
155
156
/**
157
 * Move data from one block to another.
158
 */
159
106655
void BlockItem::MakeDataMove(BlockItem *other) {
160
106655
  assert(type_ == kBlockHollow);
161
106655
  assert(other->type_ == kBlockData);
162
106655
  assert(other->size_ > 0);
163
164
106655
  type_ = kBlockData;
165
106655
  capacity_ = size_ = other->size_;
166
106655
  data_ = other->data_;
167
106655
  allocator_ = other->allocator_;
168
169
106655
  other->Discharge();
170
106655
}
171
172
173
/**
174
 * Copy a piece of one block's data into a new block.
175
 */
176
494026
void BlockItem::MakeDataCopy(
177
  const unsigned char *data,
178
  uint32_t size)
179
{
180
494026
  assert(type_ == kBlockHollow);
181
494026
  assert(allocator_ != NULL);
182
494026
  assert(size > 0);
183
184
494026
  type_ = kBlockData;
185
494026
  capacity_ = size_ = size;
186
494026
  data_ = reinterpret_cast<unsigned char *>(allocator_->Malloc(capacity_));
187
494038
  memcpy(data_, data, size);
188
494038
  atomic_xadd64(&managed_bytes_, static_cast<int64_t>(capacity_));
189
494040
}
190
191
192
119584
void BlockItem::Reset() {
193
119584
  assert(type_ == kBlockData);
194
195
119584
  atomic_xadd64(&managed_bytes_, -static_cast<int64_t>(capacity_));
196
119584
  allocator_->Free(data_);
197
119584
  data_ = NULL;
198
119584
  size_ = capacity_ = 0;
199
119584
  type_ = kBlockHollow;
200
119584
}
201
202
203
927293
void BlockItem::SetChunkItem(ChunkItem *value) {
204
927293
  assert(value != NULL);
205
927293
  assert(chunk_item_ == NULL);
206
927293
  chunk_item_ = value;
207
927293
}
208
209
210
1153556
void BlockItem::SetFileItem(FileItem *value) {
211
1153556
  assert(value != NULL);
212
1153556
  assert(file_item_ == NULL);
213
1153556
  file_item_ = value;
214
1153556
}
215
216
217
512
uint32_t BlockItem::Write(void *buf, uint32_t count) {
218
512
  assert(type_ == kBlockData);
219
220
512
  uint32_t remaining = capacity_ - size_;
221
512
  uint32_t nbytes = std::min(remaining, count);
222
512
  memcpy(data_ + size_, buf, nbytes);
223
512
  size_ += nbytes;
224
512
  return nbytes;
225

45
}