forked from root-project/root
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TEveChunkManager.cxx
155 lines (132 loc) · 4.03 KB
/
TEveChunkManager.cxx
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// @(#)root/eve:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
/*************************************************************************
* Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include "TEveChunkManager.h"
/** \class TEveChunkManager
\ingroup TEve
Vector-like container with chunked memory allocation.
Allocation chunk can accommodate fN atoms of byte-size fS each.
The chunks themselves are TArrayCs and are stored in a std::vector<TArrayC*>.
Holes in the structure are not supported, neither is removal of atoms.
The structure can be Refit() to occupy a single contiguous array.
*/
ClassImp(TEveChunkManager);
ClassImp(TEveChunkManager::iterator);
////////////////////////////////////////////////////////////////////////////////
/// Release all memory chunks.
void TEveChunkManager::ReleaseChunks()
{
for (Int_t i=0; i<fVecSize; ++i)
delete fChunks[i];
fChunks.clear();
}
////////////////////////////////////////////////////////////////////////////////
/// Default constructor.
/// Call reset for initialization.
TEveChunkManager::TEveChunkManager() :
fS(0), fN(0),
fSize(0), fVecSize(0), fCapacity(0)
{
}
////////////////////////////////////////////////////////////////////////////////
/// Constructor.
TEveChunkManager::TEveChunkManager(Int_t atom_size, Int_t chunk_size) :
fS(atom_size), fN(chunk_size),
fSize(0), fVecSize(0), fCapacity(0)
{
}
////////////////////////////////////////////////////////////////////////////////
/// Destructor.
TEveChunkManager::~TEveChunkManager()
{
ReleaseChunks();
}
////////////////////////////////////////////////////////////////////////////////
/// Empty the container and reset it with given atom and chunk sizes.
void TEveChunkManager::Reset(Int_t atom_size, Int_t chunk_size)
{
ReleaseChunks();
fS = atom_size;
fN = chunk_size;
fSize = fVecSize = fCapacity = 0;
}
////////////////////////////////////////////////////////////////////////////////
/// Refit the container so that all current data fits into a single
/// chunk.
void TEveChunkManager::Refit()
{
if (fSize == 0 || (fVecSize == 1 && fSize == fCapacity))
return;
TArrayC* one = new TArrayC(fS*fSize);
Char_t* pos = one->fArray;
for (Int_t i=0; i<fVecSize; ++i)
{
Int_t size = fS * NAtoms(i);
memcpy(pos, fChunks[i]->fArray, size);
pos += size;
}
ReleaseChunks();
fN = fCapacity = fSize;
fVecSize = 1;
fChunks.push_back(one);
}
////////////////////////////////////////////////////////////////////////////////
/// Allocate a new memory chunk and register it.
Char_t* TEveChunkManager::NewChunk()
{
fChunks.push_back(new TArrayC(fS*fN));
++fVecSize;
fCapacity += fN;
return fChunks.back()->fArray;
}
////////////////////////////////////////////////////////////////////////////////
/// Go to next atom.
Bool_t TEveChunkManager::iterator::next()
{
if (fSelection == 0)
{
if (fAtomsToGo <= 0)
{
if (fNextChunk < fPlex->VecSize())
{
fCurrent = fPlex->Chunk(fNextChunk);
fAtomsToGo = fPlex->NAtoms(fNextChunk);
++fNextChunk;
}
else
{
return kFALSE;
}
}
else
{
fCurrent += fPlex->S();
}
++fAtomIndex;
--fAtomsToGo;
return kTRUE;
}
else
{
if (fAtomIndex == -1)
fSelectionIterator = fSelection->begin();
else
++fSelectionIterator;
if (fSelectionIterator != fSelection->end())
{
fAtomIndex = *fSelectionIterator;
fCurrent = fPlex->Atom(fAtomIndex);
return kTRUE;
}
else
{
return kFALSE;
}
}
}