-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathDataBlockContainer.h
More file actions
124 lines (100 loc) · 4.05 KB
/
Copy pathDataBlockContainer.h
File metadata and controls
124 lines (100 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
#ifndef DATAFORMAT_DATABLOCKCONTAINER
#define DATAFORMAT_DATABLOCKCONTAINER
#include <Common/MemPool.h>
#include <functional>
#include <memory>
#include <stdint.h>
#include <stdlib.h>
//#define DATABLOCKCONTAINER_DEBUG
#ifdef DATABLOCKCONTAINER_DEBUG
#include <stdio.h>
#endif
#include "DataBlock.h"
// A container class for data blocks.
// In particular, allows to take care of the block release after use.
class DataBlockContainer;
using DataBlockContainerReference = std::shared_ptr<DataBlockContainer>;
class MemoryPagesPool;
class DataBlockContainer
{
public:
using ReleaseCallback = std::function<void(void)>;
// NB: may use std::bind to add extra arguments
// default constructor
DataBlockContainer(DataBlock* v_data = nullptr, uint64_t v_dataBufferSize = 0) : data(v_data), dataBufferSize(v_dataBufferSize), releaseCallback(nullptr){
#ifdef DATABLOCKCONTAINER_DEBUG
printf("Creating DataBlockContainer @ %p size %d\n", data, (int)v_dataBufferSize);
#endif
};
// this constructor allows to specify a callback which is invoked when container is destroyed
DataBlockContainer(ReleaseCallback v_callback = nullptr, DataBlock* v_data = nullptr, uint64_t v_dataBufferSize = 0) : data(v_data), dataBufferSize(v_dataBufferSize), releaseCallback(v_callback){};
// destructor
virtual ~DataBlockContainer()
{
if (releaseCallback != nullptr) {
releaseCallback();
}
#ifdef DATABLOCKCONTAINER_DEBUG
printf("Releasing DataBlockContainer @ %p\n", data);
#endif
};
DataBlock* getData()
{
return data;
};
uint64_t getDataBufferSize()
{
return dataBufferSize;
};
MemoryPagesPool *memoryPagesPoolPtr = nullptr; // to keep track of owner of this container
static DataBlockContainerReference getChildBlock(DataBlockContainerReference parentBlock, uint64_t v_dataBufferSizeNeeded, uint64_t roundUp = 0) {
uint64_t bufferSize = v_dataBufferSizeNeeded + sizeof(DataBlock);
if (roundUp) {
uint64_t r = bufferSize % roundUp;
if (r) {
bufferSize += roundUp - r;
}
}
if (bufferSize > parentBlock->getData()->header.dataSize - parentBlock->dataBufferUsed) {
return nullptr;
}
DataBlock *b = (DataBlock *)&((char *)parentBlock->getData()->data)[parentBlock->dataBufferUsed];
b->header = defaultDataBlockHeader;
b->header.dataSize = v_dataBufferSizeNeeded;
b->header.memorySize = 0; // if this is a child block, it virtually takes no memory. The memory is owned by the parent block.
b->data = &(((char*)b)[sizeof(DataBlock)]);
#ifdef DATABLOCKCONTAINER_DEBUG
printf("Block %p - creating child @ %p - payload size %d\n", parentBlock->getData(), b, (int)v_dataBufferSizeNeeded);
#endif
DataBlockContainerReference childBlock = std::make_shared<DataBlockContainer>(b, bufferSize);
if (childBlock == nullptr) {
return nullptr;
}
parentBlock->dataBufferUsed += bufferSize;
childBlock->parentBlock = parentBlock;
return childBlock;
};
bool isChildBlock() {
return (parentBlock != nullptr);
}
DataBlockContainerReference getParent() {
return parentBlock;
}
protected:
DataBlock* data; // The DataBlock in use
uint64_t dataBufferSize = 0; // Usable memory size pointed by data. Unspecified if zero.
ReleaseCallback releaseCallback; // Function called on object destroy, to release dataBlock.
DataBlockContainerReference parentBlock = nullptr; // reference to parent block used, if any
uint64_t dataBufferUsed = 0; // size of buffer used for child blocks.
};
#endif