// @(#)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"

//______________________________________________________________________________
//
// 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);

//______________________________________________________________________________
void TEveChunkManager::ReleaseChunks()
{
   // Release all memory chunks.

   for (Int_t i=0; i<fVecSize; ++i)
      delete fChunks[i];
   fChunks.clear();
}

//______________________________________________________________________________
TEveChunkManager::TEveChunkManager() :
   fS(0), fN(0),
   fSize(0), fVecSize(0), fCapacity(0)
{
   // Default constructor.
   // Call reset for initialization.
}

//______________________________________________________________________________
TEveChunkManager::TEveChunkManager(Int_t atom_size, Int_t chunk_size) :
   fS(atom_size), fN(chunk_size),
   fSize(0), fVecSize(0), fCapacity(0)
{
   // Constructor.
}

//______________________________________________________________________________
TEveChunkManager::~TEveChunkManager()
{
   // Destructor.

   ReleaseChunks();
}

/******************************************************************************/

//______________________________________________________________________________
void TEveChunkManager::Reset(Int_t atom_size, Int_t chunk_size)
{
   // Empty the container and reset it with given atom and chunk sizes.

   ReleaseChunks();
   fS = atom_size;
   fN = chunk_size;
   fSize = fVecSize = fCapacity = 0;
}

//______________________________________________________________________________
void TEveChunkManager::Refit()
{
   // Refit the container so that all current data fits into a single
   // chunk.

   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);
}

/******************************************************************************/

//______________________________________________________________________________
Char_t* TEveChunkManager::NewChunk()
{
   // Allocate a new memory chunk and register it.

   fChunks.push_back(new TArrayC(fS*fN));
   ++fVecSize;
   fCapacity += fN;
   return fChunks.back()->fArray;
}

/******************************************************************************/

//______________________________________________________________________________
Bool_t TEveChunkManager::iterator::next()
{
   // Go to next atom.

   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;
      }
   }
}
 TEveChunkManager.cxx:1
 TEveChunkManager.cxx:2
 TEveChunkManager.cxx:3
 TEveChunkManager.cxx:4
 TEveChunkManager.cxx:5
 TEveChunkManager.cxx:6
 TEveChunkManager.cxx:7
 TEveChunkManager.cxx:8
 TEveChunkManager.cxx:9
 TEveChunkManager.cxx:10
 TEveChunkManager.cxx:11
 TEveChunkManager.cxx:12
 TEveChunkManager.cxx:13
 TEveChunkManager.cxx:14
 TEveChunkManager.cxx:15
 TEveChunkManager.cxx:16
 TEveChunkManager.cxx:17
 TEveChunkManager.cxx:18
 TEveChunkManager.cxx:19
 TEveChunkManager.cxx:20
 TEveChunkManager.cxx:21
 TEveChunkManager.cxx:22
 TEveChunkManager.cxx:23
 TEveChunkManager.cxx:24
 TEveChunkManager.cxx:25
 TEveChunkManager.cxx:26
 TEveChunkManager.cxx:27
 TEveChunkManager.cxx:28
 TEveChunkManager.cxx:29
 TEveChunkManager.cxx:30
 TEveChunkManager.cxx:31
 TEveChunkManager.cxx:32
 TEveChunkManager.cxx:33
 TEveChunkManager.cxx:34
 TEveChunkManager.cxx:35
 TEveChunkManager.cxx:36
 TEveChunkManager.cxx:37
 TEveChunkManager.cxx:38
 TEveChunkManager.cxx:39
 TEveChunkManager.cxx:40
 TEveChunkManager.cxx:41
 TEveChunkManager.cxx:42
 TEveChunkManager.cxx:43
 TEveChunkManager.cxx:44
 TEveChunkManager.cxx:45
 TEveChunkManager.cxx:46
 TEveChunkManager.cxx:47
 TEveChunkManager.cxx:48
 TEveChunkManager.cxx:49
 TEveChunkManager.cxx:50
 TEveChunkManager.cxx:51
 TEveChunkManager.cxx:52
 TEveChunkManager.cxx:53
 TEveChunkManager.cxx:54
 TEveChunkManager.cxx:55
 TEveChunkManager.cxx:56
 TEveChunkManager.cxx:57
 TEveChunkManager.cxx:58
 TEveChunkManager.cxx:59
 TEveChunkManager.cxx:60
 TEveChunkManager.cxx:61
 TEveChunkManager.cxx:62
 TEveChunkManager.cxx:63
 TEveChunkManager.cxx:64
 TEveChunkManager.cxx:65
 TEveChunkManager.cxx:66
 TEveChunkManager.cxx:67
 TEveChunkManager.cxx:68
 TEveChunkManager.cxx:69
 TEveChunkManager.cxx:70
 TEveChunkManager.cxx:71
 TEveChunkManager.cxx:72
 TEveChunkManager.cxx:73
 TEveChunkManager.cxx:74
 TEveChunkManager.cxx:75
 TEveChunkManager.cxx:76
 TEveChunkManager.cxx:77
 TEveChunkManager.cxx:78
 TEveChunkManager.cxx:79
 TEveChunkManager.cxx:80
 TEveChunkManager.cxx:81
 TEveChunkManager.cxx:82
 TEveChunkManager.cxx:83
 TEveChunkManager.cxx:84
 TEveChunkManager.cxx:85
 TEveChunkManager.cxx:86
 TEveChunkManager.cxx:87
 TEveChunkManager.cxx:88
 TEveChunkManager.cxx:89
 TEveChunkManager.cxx:90
 TEveChunkManager.cxx:91
 TEveChunkManager.cxx:92
 TEveChunkManager.cxx:93
 TEveChunkManager.cxx:94
 TEveChunkManager.cxx:95
 TEveChunkManager.cxx:96
 TEveChunkManager.cxx:97
 TEveChunkManager.cxx:98
 TEveChunkManager.cxx:99
 TEveChunkManager.cxx:100
 TEveChunkManager.cxx:101
 TEveChunkManager.cxx:102
 TEveChunkManager.cxx:103
 TEveChunkManager.cxx:104
 TEveChunkManager.cxx:105
 TEveChunkManager.cxx:106
 TEveChunkManager.cxx:107
 TEveChunkManager.cxx:108
 TEveChunkManager.cxx:109
 TEveChunkManager.cxx:110
 TEveChunkManager.cxx:111
 TEveChunkManager.cxx:112
 TEveChunkManager.cxx:113
 TEveChunkManager.cxx:114
 TEveChunkManager.cxx:115
 TEveChunkManager.cxx:116
 TEveChunkManager.cxx:117
 TEveChunkManager.cxx:118
 TEveChunkManager.cxx:119
 TEveChunkManager.cxx:120
 TEveChunkManager.cxx:121
 TEveChunkManager.cxx:122
 TEveChunkManager.cxx:123
 TEveChunkManager.cxx:124
 TEveChunkManager.cxx:125
 TEveChunkManager.cxx:126
 TEveChunkManager.cxx:127
 TEveChunkManager.cxx:128
 TEveChunkManager.cxx:129
 TEveChunkManager.cxx:130
 TEveChunkManager.cxx:131
 TEveChunkManager.cxx:132
 TEveChunkManager.cxx:133
 TEveChunkManager.cxx:134
 TEveChunkManager.cxx:135
 TEveChunkManager.cxx:136
 TEveChunkManager.cxx:137
 TEveChunkManager.cxx:138
 TEveChunkManager.cxx:139
 TEveChunkManager.cxx:140
 TEveChunkManager.cxx:141
 TEveChunkManager.cxx:142
 TEveChunkManager.cxx:143
 TEveChunkManager.cxx:144
 TEveChunkManager.cxx:145
 TEveChunkManager.cxx:146
 TEveChunkManager.cxx:147
 TEveChunkManager.cxx:148
 TEveChunkManager.cxx:149
 TEveChunkManager.cxx:150
 TEveChunkManager.cxx:151
 TEveChunkManager.cxx:152
 TEveChunkManager.cxx:153
 TEveChunkManager.cxx:154
 TEveChunkManager.cxx:155
 TEveChunkManager.cxx:156
 TEveChunkManager.cxx:157
 TEveChunkManager.cxx:158
 TEveChunkManager.cxx:159