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

#ifndef ROOT_TEveChunkManager
#define ROOT_TEveChunkManager

#include "TEveUtil.h"

#include "TObject.h"
#include "TArrayC.h"

#include <vector>


/******************************************************************************/
// TEveChunkManager
/******************************************************************************/

class TEveChunkManager
{
private:
   TEveChunkManager(const TEveChunkManager&);            // Not implemented
   TEveChunkManager& operator=(const TEveChunkManager&); // Not implemented

protected:
   Int_t fS;        // Size of atom
   Int_t fN;        // Number of atoms in a chunk

   Int_t fSize;     // Size of container, number of atoms
   Int_t fVecSize;  // Number of allocated chunks
   Int_t fCapacity; // Available capacity within the chunks

   std::vector<TArrayC*> fChunks; // Memory blocks

   void ReleaseChunks();

public:
   TEveChunkManager();
   TEveChunkManager(Int_t atom_size, Int_t chunk_size);
   virtual ~TEveChunkManager();

   void Reset(Int_t atom_size, Int_t chunk_size);
   void Refit();

   Int_t    S() const { return fS; }
   Int_t    N() const { return fN; }

   Int_t    Size()     const { return fSize; }
   Int_t    VecSize()  const { return fVecSize; }
   Int_t    Capacity() const { return fCapacity; }

   Char_t* Atom(Int_t idx)   const { return fChunks[idx/fN]->fArray + idx%fN*fS; }
   Char_t* Chunk(Int_t chk)  const { return fChunks[chk]->fArray; }
   Int_t   NAtoms(Int_t chk) const { return (chk < fVecSize-1) ? fN : (fSize-1)%fN + 1; }

   Char_t* NewAtom();
   Char_t* NewChunk();


   // Iterator

   struct iterator
   {
      TEveChunkManager *fPlex;
      Char_t           *fCurrent;
      Int_t             fAtomIndex;
      Int_t             fNextChunk;
      Int_t             fAtomsToGo;

      const std::set<Int_t>           *fSelection;
      std::set<Int_t>::const_iterator  fSelectionIterator;

      iterator(TEveChunkManager* p) :
         fPlex(p), fCurrent(0), fAtomIndex(-1),
         fNextChunk(0), fAtomsToGo(0), fSelection(0), fSelectionIterator() {}
      iterator(TEveChunkManager& p) :
         fPlex(&p), fCurrent(0), fAtomIndex(-1),
         fNextChunk(0), fAtomsToGo(0), fSelection(0), fSelectionIterator() {}
      iterator(const iterator& i) :
         fPlex(i.fPlex), fCurrent(i.fCurrent), fAtomIndex(i.fAtomIndex),
         fNextChunk(i.fNextChunk), fAtomsToGo(i.fAtomsToGo),
         fSelection(i.fSelection), fSelectionIterator(i.fSelectionIterator) {}

      iterator& operator=(const iterator& i) {
         fPlex = i.fPlex; fCurrent = i.fCurrent; fAtomIndex = i.fAtomIndex;
         fNextChunk = i.fNextChunk; fAtomsToGo = i.fAtomsToGo;
         fSelection = i.fSelection; fSelectionIterator = i.fSelectionIterator;
         return *this;
      }

      Bool_t  next();
      void    reset() { fCurrent = 0; fAtomIndex = -1; fNextChunk = fAtomsToGo = 0; }

      Char_t* operator()() { return fCurrent; }
      Char_t* operator*()  { return fCurrent; }
      Int_t   index()      { return fAtomIndex; }
   };

   ClassDef(TEveChunkManager, 1); // Vector-like container with chunked memory allocation.
};


//______________________________________________________________________________
inline Char_t* TEveChunkManager::NewAtom()
{
   Char_t *a = (fSize >= fCapacity) ? NewChunk() : Atom(fSize);
   ++fSize;
   return a;
}


/******************************************************************************/
// Templated some-class TEveChunkVector
/******************************************************************************/

template<class T>
class TEveChunkVector : public TEveChunkManager
{
private:
   TEveChunkVector(const TEveChunkVector&);            // Not implemented
   TEveChunkVector& operator=(const TEveChunkVector&); // Not implemented

public:
   TEveChunkVector()                 : TEveChunkManager() {}
   TEveChunkVector(Int_t chunk_size) : TEveChunkManager(sizeof(T), chunk_size) {}
   virtual ~TEveChunkVector() {}

   void Reset(Int_t chunk_size) { Reset(sizeof(T), chunk_size); }

   T* At(Int_t idx)  { return reinterpret_cast<T*>(Atom(idx)); }
   T& Ref(Int_t idx) { return *At(idx); }

   ClassDef(TEveChunkVector, 1); // Templated class for specific atom classes (given as template argument).
};

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