Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
REveChunkManager.cxx
Go to the documentation of this file.
1 // @(#)root/eve7:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
13 
14 using namespace ROOT::Experimental;
15 
16 /** \class REveChunkManager
17 \ingroup REve
18 Vector-like container with chunked memory allocation.
19 
20 Allocation chunk can accommodate fN atoms of byte-size fS each.
21 The chunks themselves are TArrayCs and are stored in a std::vector<TArrayC*>.
22 Holes in the structure are not supported, neither is removal of atoms.
23 The structure can be Refit() to occupy a single contiguous array.
24 */
25 
26 
27 ////////////////////////////////////////////////////////////////////////////////
28 /// Release all memory chunks.
29 
30 void REveChunkManager::ReleaseChunks()
31 {
32  for (Int_t i=0; i<fVecSize; ++i)
33  delete fChunks[i];
34  fChunks.clear();
35 }
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Default constructor.
39 /// Call reset for initialization.
40 
41 REveChunkManager::REveChunkManager() :
42  fS(0), fN(0),
43  fSize(0), fVecSize(0), fCapacity(0)
44 {
45 }
46 
47 ////////////////////////////////////////////////////////////////////////////////
48 /// Constructor.
49 
50 REveChunkManager::REveChunkManager(Int_t atom_size, Int_t chunk_size) :
51  fS(atom_size), fN(chunk_size),
52  fSize(0), fVecSize(0), fCapacity(0)
53 {
54 }
55 
56 ////////////////////////////////////////////////////////////////////////////////
57 /// Destructor.
58 
59 REveChunkManager::~REveChunkManager()
60 {
61  ReleaseChunks();
62 }
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 /// Empty the container and reset it with given atom and chunk sizes.
66 
67 void REveChunkManager::Reset(Int_t atom_size, Int_t chunk_size)
68 {
69  ReleaseChunks();
70  fS = atom_size;
71  fN = chunk_size;
72  fSize = fVecSize = fCapacity = 0;
73 }
74 
75 ////////////////////////////////////////////////////////////////////////////////
76 /// Refit the container so that all current data fits into a single
77 /// chunk.
78 
79 void REveChunkManager::Refit()
80 {
81  if (fSize == 0 || (fVecSize == 1 && fSize == fCapacity))
82  return;
83 
84  TArrayC* one = new TArrayC(fS*fSize);
85  Char_t* pos = one->fArray;
86  for (Int_t i=0; i<fVecSize; ++i)
87  {
88  Int_t size = fS * NAtoms(i);
89  memcpy(pos, fChunks[i]->fArray, size);
90  pos += size;
91  }
92  ReleaseChunks();
93  fN = fCapacity = fSize;
94  fVecSize = 1;
95  fChunks.push_back(one);
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Allocate a new memory chunk and register it.
100 
101 Char_t* REveChunkManager::NewChunk()
102 {
103  fChunks.push_back(new TArrayC(fS*fN));
104  ++fVecSize;
105  fCapacity += fN;
106  return fChunks.back()->fArray;
107 }
108 
109 ////////////////////////////////////////////////////////////////////////////////
110 /// Go to next atom.
111 
112 Bool_t REveChunkManager::iterator::next()
113 {
114  if (fSelection == nullptr)
115  {
116  if (fAtomsToGo <= 0)
117  {
118  if (fNextChunk < fPlex.VecSize())
119  {
120  fCurrent = fPlex.Chunk(fNextChunk);
121  fAtomsToGo = fPlex.NAtoms(fNextChunk);
122  ++fNextChunk;
123  }
124  else
125  {
126  return kFALSE;
127  }
128  }
129  else
130  {
131  fCurrent += fPlex.S();
132  }
133  ++fAtomIndex;
134  --fAtomsToGo;
135  return kTRUE;
136  }
137  else
138  {
139  if (fAtomIndex == -1)
140  fSelectionIterator = fSelection->begin();
141  else
142  ++fSelectionIterator;
143 
144  if (fSelectionIterator != fSelection->end())
145  {
146  fAtomIndex = *fSelectionIterator;
147  fCurrent = fPlex.Atom(fAtomIndex);
148  return kTRUE;
149  }
150  else
151  {
152  return kFALSE;
153  }
154  }
155 }