// @(#)root/io:$Id$
// Author: Elvin Sindrilaru   19/05/2011

/*************************************************************************
 * Copyright (C) 1995-2011, 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 "TFilePrefetch.h"
#include "TTimeStamp.h"
#include "TVirtualPerfStats.h"
#include "TVirtualMonitoring.h"

#include <iostream>
#include <string>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cctype>

static const int kMAX_READ_SIZE    = 2;   //maximum size of the read list of blocks

inline int xtod(char c) { return (c>='0' && c<='9') ? c-'0' : ((c>='A' && c<='F') ? c-'A'+10 : ((c>='a' && c<='f') ? c-'a'+10 : 0)); }

using namespace std;

ClassImp(TFilePrefetch)

//____________________________________________________________________________________________
TFilePrefetch::TFilePrefetch(TFile* file) :
  fFile(file),
  fConsumer(0),
  fThreadJoined(kTRUE)
{
   // Constructor.

   fPendingBlocks    = new TList();
   fReadBlocks       = new TList();

   fPendingBlocks->SetOwner();
   fReadBlocks->SetOwner();

   fMutexReadList    = new TMutex();
   fMutexPendingList = new TMutex();
   fNewBlockAdded    = new TCondition(0);
   fReadBlockAdded   = new TCondition(0);
   fSemMasterWorker  = new TSemaphore(0);
   fSemWorkerMaster  = new TSemaphore(0);
   fSemChangeFile    = new TSemaphore(0);
}

//____________________________________________________________________________________________
TFilePrefetch::~TFilePrefetch()
{
   // Destructor

   if (!fThreadJoined) {
     WaitFinishPrefetch();
   }

   SafeDelete(fConsumer);
   SafeDelete(fPendingBlocks);
   SafeDelete(fReadBlocks);
   SafeDelete(fMutexReadList);
   SafeDelete(fMutexPendingList);
   SafeDelete(fNewBlockAdded);
   SafeDelete(fReadBlockAdded);
   SafeDelete(fSemMasterWorker);
   SafeDelete(fSemWorkerMaster);
   SafeDelete(fSemChangeFile);
}


//____________________________________________________________________________________________
void TFilePrefetch::WaitFinishPrefetch()
{
   // Killing the async prefetching thread

   fSemMasterWorker->Post();

   TMutex *mutexCond = fNewBlockAdded->GetMutex();
   while ( fSemWorkerMaster->Wait(10) != 0 ) {
      mutexCond->Lock();
      fNewBlockAdded->Signal();
      mutexCond->UnLock();
   }

   fConsumer->Join();
   fThreadJoined=kTRUE;
}


//____________________________________________________________________________________________
void TFilePrefetch::ReadAsync(TFPBlock* block, Bool_t &inCache)
{
   // Read one block and insert it in prefetchBuffers list.

   char* path = 0;

   if (CheckBlockInCache(path, block)){
      block->SetBuffer(GetBlockFromCache(path, block->GetDataSize()));
      inCache = kTRUE;
   }
   else{
      fFile->ReadBuffers(block->GetBuffer(), block->GetPos(), block->GetLen(), block->GetNoElem());
      if (fFile->GetArchive()) {
         for (Int_t i = 0; i < block->GetNoElem(); i++)
            block->SetPos(i, block->GetPos(i) - fFile->GetArchiveOffset());
      }
      inCache =kFALSE;
   }
   delete[] path;
}

//____________________________________________________________________________________________
void TFilePrefetch::ReadListOfBlocks()
{
   // Get blocks specified in prefetchBlocks.

   Bool_t inCache = kFALSE;
   TFPBlock*  block = 0;

   while((block = GetPendingBlock())){
      ReadAsync(block, inCache);
      AddReadBlock(block);
      if (!inCache)
         SaveBlockInCache(block);
   }
}

//____________________________________________________________________________________________
Bool_t TFilePrefetch::BinarySearchReadList(TFPBlock* blockObj, Long64_t offset, Int_t len, Int_t* index)
{
   // Search for a requested element in a block and return the index.

   Int_t first = 0, last = -1, mid = -1;
   last = (Int_t) blockObj->GetNoElem()-1;

   while (first <= last){
      mid = first + (last - first) / 2;
      if ((offset >= blockObj->GetPos(mid) && offset <= (blockObj->GetPos(mid) + blockObj->GetLen(mid))
           && ( (offset + len) <= blockObj->GetPos(mid) + blockObj->GetLen(mid)))){

         *index = mid;
         return true;
      }
      else if (blockObj->GetPos(mid) < offset){
         first = mid + 1;
      }
      else{
         last = mid - 1;
      }
   }
   return false;
}

//____________________________________________________________________________________________
Long64_t TFilePrefetch::GetWaitTime()
{
   // Return the time spent wating for buffer to be read in microseconds.

   return Long64_t(fWaitTime.RealTime()*1.e+6);
}

//____________________________________________________________________________________________
Bool_t TFilePrefetch::ReadBuffer(char* buf, Long64_t offset, Int_t len)
{
   // Return a prefetched element.

   Bool_t found = false;
   TFPBlock* blockObj = 0;
   TMutex *mutexBlocks = fMutexReadList;
   Int_t index = -1;

   while (1){
      mutexBlocks->Lock();
      TIter iter(fReadBlocks);
      while ((blockObj = (TFPBlock*) iter.Next())){
         index = -1;
         if (BinarySearchReadList(blockObj, offset, len, &index)){
            found = true;
            break;
         }
      }
      if (found)
         break;
      else{
         mutexBlocks->UnLock();

         fWaitTime.Start(kFALSE);
         fReadBlockAdded->Wait(); //wait for a new block to be added
         fWaitTime.Stop();
      }
   }

   if (found){
      char *pBuff = blockObj->GetPtrToPiece(index);
      pBuff += (offset - blockObj->GetPos(index));
      memcpy(buf, pBuff, len);
   }
   mutexBlocks->UnLock();
   return found;
}

//____________________________________________________________________________________________
void TFilePrefetch::ReadBlock(Long64_t* offset, Int_t* len, Int_t nblock)
{
   // Create a TFPBlock object or recycle one and add it to the prefetchBlocks list.

   TFPBlock* block = CreateBlockObj(offset, len, nblock);
   AddPendingBlock(block);
}

//____________________________________________________________________________________________
void TFilePrefetch::AddPendingBlock(TFPBlock* block)
{
   // Safe method to add a block to the pendingList.

   TMutex *mutexBlocks = fMutexPendingList;
   TMutex *mutexCond = fNewBlockAdded->GetMutex();

   mutexBlocks->Lock();
   fPendingBlocks->Add(block);
   mutexBlocks->UnLock();

   mutexCond->Lock();
   fNewBlockAdded->Signal();
   mutexCond->UnLock();
}

//____________________________________________________________________________________________
TFPBlock* TFilePrefetch::GetPendingBlock()
{
   // Safe method to remove a block from the pendingList.

   TFPBlock* block = 0;
   TMutex *mutex = fMutexPendingList;
   mutex->Lock();

   if (fPendingBlocks->GetSize()){
      block = (TFPBlock*)fPendingBlocks->First();
      block = (TFPBlock*)fPendingBlocks->Remove(block);
   }
   mutex->UnLock();
   return block;
}

//____________________________________________________________________________________________
void TFilePrefetch::AddReadBlock(TFPBlock* block)
{
   // Safe method to add a block to the readList.

   TMutex *mutexCond = fReadBlockAdded->GetMutex();
   TMutex *mutex = fMutexReadList;
   mutex->Lock();

   if (fReadBlocks->GetSize() >= kMAX_READ_SIZE){
      TFPBlock* movedBlock = (TFPBlock*) fReadBlocks->First();
      movedBlock = (TFPBlock*)fReadBlocks->Remove(movedBlock);
      delete movedBlock;
      movedBlock = 0;
   }

   fReadBlocks->Add(block);
   mutex->UnLock();

   //signal the addition of a new block
   mutexCond->Lock();
   fReadBlockAdded->Signal();
   mutexCond->UnLock();
}


//____________________________________________________________________________________________
TFPBlock* TFilePrefetch::CreateBlockObj(Long64_t* offset, Int_t* len, Int_t noblock)
{
   // Create a new block or recycle an old one.

   TFPBlock* blockObj = 0;
   TMutex *mutex = fMutexReadList;

   mutex->Lock();

   if (fReadBlocks->GetSize() >= kMAX_READ_SIZE){
      blockObj = static_cast<TFPBlock*>(fReadBlocks->First());
      fReadBlocks->Remove(blockObj);
      mutex->UnLock();
      blockObj->ReallocBlock(offset, len, noblock);
   }
   else{
      mutex->UnLock();
      blockObj = new TFPBlock(offset, len, noblock);
   }
   return blockObj;
}

//____________________________________________________________________________________________
TThread* TFilePrefetch::GetThread() const
{
   // Return reference to the consumer thread.

   return fConsumer;
}


//____________________________________________________________________________________________
void TFilePrefetch::SetFile(TFile *file)
{
   // Change the file
   // When prefetching is enabled we also need to:
   // - make sure the async thread is not doing any work
   // - clear all blocks from prefetching and read list
   // - reset the file pointer

   if (!fThreadJoined) {
     fSemChangeFile->Wait();
   }

   if (fFile) {
     // Remove all pending and read blocks
     fMutexPendingList->Lock();
     fPendingBlocks->Clear();
     fMutexPendingList->UnLock();

     fMutexReadList->Lock();
     fReadBlocks->Clear();
     fMutexReadList->UnLock();
   }

   fFile = file;
   if (!fThreadJoined) {
     fSemChangeFile->Post();
   }
}


//____________________________________________________________________________________________
Int_t TFilePrefetch::ThreadStart()
{
   // Used to start the consumer thread.
   int rc;

   fConsumer = new TThread((TThread::VoidRtnFunc_t) ThreadProc, (void*) this);
   rc = fConsumer->Run();
   if ( !rc ) {
      fThreadJoined = kFALSE;
   }
   return rc;
}


//____________________________________________________________________________________________
TThread::VoidRtnFunc_t TFilePrefetch::ThreadProc(void* arg)
{
   // Execution loop of the consumer thread.

   TFilePrefetch* pClass = (TFilePrefetch*) arg;
   TSemaphore* semChangeFile = pClass->fSemChangeFile;
   semChangeFile->Post();
   pClass->fNewBlockAdded->Wait();
   semChangeFile->Wait();

   while( pClass->fSemMasterWorker->TryWait() != 0 ) {
      pClass->ReadListOfBlocks();

      // Use the semaphore to deal with the case when the file pointer
      // is changed on the fly by TChain
      semChangeFile->Post();
      pClass->fNewBlockAdded->Wait();
      semChangeFile->Wait();
   }

   pClass->fSemWorkerMaster->Post();
   return (TThread::VoidRtnFunc_t) 1;
}

//############################# CACHING PART ###################################

//____________________________________________________________________________________________
Int_t TFilePrefetch::SumHex(const char *hex)
{
   // Sum up individual hex values to obtain a decimal value.

   Int_t result = 0;
   const char* ptr = hex;

   for(Int_t i=0; i < (Int_t)strlen(hex); i++)
      result += xtod(ptr[i]);

   return result;
}

//____________________________________________________________________________________________
Bool_t TFilePrefetch::CheckBlockInCache(char*& path, TFPBlock* block)
{
   // Test if the block is in cache.

   if (fPathCache == "")
      return false;

   Bool_t found = false;
   TString fullPath(fPathCache); // path of the cached files.

   Int_t value = 0;

   if (!gSystem->OpenDirectory(fullPath))
      gSystem->mkdir(fullPath);

   //dir is SHA1 value modulo 16; filename is the value of the SHA1(offset+len)
   TMD5* md = new TMD5();

   TString concatStr;
   for (Int_t i=0; i < block->GetNoElem(); i++){
      concatStr.Form("%lld", block->GetPos(i));
      md->Update((UChar_t*)concatStr.Data(), concatStr.Length());
   }

   md->Final();
   TString fileName( md->AsString() );
   value = SumHex(fileName);
   value = value % 16;
   TString dirName;
   dirName.Form("%i", value);

   fullPath += "/" + dirName + "/" + fileName;

   FileStat_t stat;
   if (gSystem->GetPathInfo(fullPath, stat) == 0) {
      path = new char[fullPath.Length() + 1];
      strlcpy(path, fullPath,fullPath.Length() + 1);
      found = true;
   } else
      found = false;

   delete md;
   return found;
}

//____________________________________________________________________________________________
char* TFilePrefetch::GetBlockFromCache(const char* path, Int_t length)
{
   // Return a buffer from cache.

   char *buffer = 0;
   TString strPath = path;

   strPath += "?filetype=raw";
   TFile* file = new TFile(strPath);

   Double_t start = 0;
   if (gPerfStats != 0) start = TTimeStamp();

   buffer = (char*) calloc(length, sizeof(char));
   file->ReadBuffer(buffer, 0, length);

   fFile->fBytesRead  += length;
   fFile->fgBytesRead += length;
   fFile->SetReadCalls(fFile->GetReadCalls() + 1);
   fFile->fgReadCalls++;

   if (gMonitoringWriter)
      gMonitoringWriter->SendFileReadProgress(fFile);
   if (gPerfStats != 0) {
      gPerfStats->FileReadEvent(fFile, length, start);
   }

   file->Close();
   delete file;
   return buffer;
}

//____________________________________________________________________________________________
void TFilePrefetch::SaveBlockInCache(TFPBlock* block)
{
   // Save the block content in cache.

   if (fPathCache == "")
      return;

   //dir is SHA1 value modulo 16; filename is the value of the SHA1
   TMD5* md = new TMD5();

   TString concatStr;
   for(Int_t i=0; i< block->GetNoElem(); i++){
      concatStr.Form("%lld", block->GetPos(i));
      md->Update((UChar_t*)concatStr.Data(), concatStr.Length());
   }
   md->Final();

   TString fileName( md->AsString() );
   Int_t value = SumHex(fileName);
   value = value % 16;

   TString fullPath( fPathCache );
   TString dirName;
   dirName.Form("%i", value);
   fullPath += ("/" + dirName);

   if (!gSystem->OpenDirectory(fullPath))
      gSystem->mkdir(fullPath);

   TFile* file = 0;
   fullPath += ("/" + fileName);
   FileStat_t stat;
   if (gSystem->GetPathInfo(fullPath, stat) == 0) {
      fullPath += "?filetype=raw";
      file = TFile::Open(fullPath, "update");
   } else{
      fullPath += "?filetype=raw";
      file = TFile::Open(fullPath, "new");
   }

   if (file) {
      // coverity[unchecked_value] We do not print error message, have not error
      // return code and close the file anyway, not need to check the return value.
      file->WriteBuffer(block->GetBuffer(), block->GetDataSize());
      file->Close();
      delete file;
   }
   delete md;
}


//____________________________________________________________________________________________
Bool_t TFilePrefetch::SetCache(const char* path)
{
   // Set the path of the cache directory.
  fPathCache = path;

  if (!gSystem->OpenDirectory(path)){
    return (!gSystem->mkdir(path) ? true : false);
  }

  // Directory already exists
  return true;
}

 TFilePrefetch.cxx:1
 TFilePrefetch.cxx:2
 TFilePrefetch.cxx:3
 TFilePrefetch.cxx:4
 TFilePrefetch.cxx:5
 TFilePrefetch.cxx:6
 TFilePrefetch.cxx:7
 TFilePrefetch.cxx:8
 TFilePrefetch.cxx:9
 TFilePrefetch.cxx:10
 TFilePrefetch.cxx:11
 TFilePrefetch.cxx:12
 TFilePrefetch.cxx:13
 TFilePrefetch.cxx:14
 TFilePrefetch.cxx:15
 TFilePrefetch.cxx:16
 TFilePrefetch.cxx:17
 TFilePrefetch.cxx:18
 TFilePrefetch.cxx:19
 TFilePrefetch.cxx:20
 TFilePrefetch.cxx:21
 TFilePrefetch.cxx:22
 TFilePrefetch.cxx:23
 TFilePrefetch.cxx:24
 TFilePrefetch.cxx:25
 TFilePrefetch.cxx:26
 TFilePrefetch.cxx:27
 TFilePrefetch.cxx:28
 TFilePrefetch.cxx:29
 TFilePrefetch.cxx:30
 TFilePrefetch.cxx:31
 TFilePrefetch.cxx:32
 TFilePrefetch.cxx:33
 TFilePrefetch.cxx:34
 TFilePrefetch.cxx:35
 TFilePrefetch.cxx:36
 TFilePrefetch.cxx:37
 TFilePrefetch.cxx:38
 TFilePrefetch.cxx:39
 TFilePrefetch.cxx:40
 TFilePrefetch.cxx:41
 TFilePrefetch.cxx:42
 TFilePrefetch.cxx:43
 TFilePrefetch.cxx:44
 TFilePrefetch.cxx:45
 TFilePrefetch.cxx:46
 TFilePrefetch.cxx:47
 TFilePrefetch.cxx:48
 TFilePrefetch.cxx:49
 TFilePrefetch.cxx:50
 TFilePrefetch.cxx:51
 TFilePrefetch.cxx:52
 TFilePrefetch.cxx:53
 TFilePrefetch.cxx:54
 TFilePrefetch.cxx:55
 TFilePrefetch.cxx:56
 TFilePrefetch.cxx:57
 TFilePrefetch.cxx:58
 TFilePrefetch.cxx:59
 TFilePrefetch.cxx:60
 TFilePrefetch.cxx:61
 TFilePrefetch.cxx:62
 TFilePrefetch.cxx:63
 TFilePrefetch.cxx:64
 TFilePrefetch.cxx:65
 TFilePrefetch.cxx:66
 TFilePrefetch.cxx:67
 TFilePrefetch.cxx:68
 TFilePrefetch.cxx:69
 TFilePrefetch.cxx:70
 TFilePrefetch.cxx:71
 TFilePrefetch.cxx:72
 TFilePrefetch.cxx:73
 TFilePrefetch.cxx:74
 TFilePrefetch.cxx:75
 TFilePrefetch.cxx:76
 TFilePrefetch.cxx:77
 TFilePrefetch.cxx:78
 TFilePrefetch.cxx:79
 TFilePrefetch.cxx:80
 TFilePrefetch.cxx:81
 TFilePrefetch.cxx:82
 TFilePrefetch.cxx:83
 TFilePrefetch.cxx:84
 TFilePrefetch.cxx:85
 TFilePrefetch.cxx:86
 TFilePrefetch.cxx:87
 TFilePrefetch.cxx:88
 TFilePrefetch.cxx:89
 TFilePrefetch.cxx:90
 TFilePrefetch.cxx:91
 TFilePrefetch.cxx:92
 TFilePrefetch.cxx:93
 TFilePrefetch.cxx:94
 TFilePrefetch.cxx:95
 TFilePrefetch.cxx:96
 TFilePrefetch.cxx:97
 TFilePrefetch.cxx:98
 TFilePrefetch.cxx:99
 TFilePrefetch.cxx:100
 TFilePrefetch.cxx:101
 TFilePrefetch.cxx:102
 TFilePrefetch.cxx:103
 TFilePrefetch.cxx:104
 TFilePrefetch.cxx:105
 TFilePrefetch.cxx:106
 TFilePrefetch.cxx:107
 TFilePrefetch.cxx:108
 TFilePrefetch.cxx:109
 TFilePrefetch.cxx:110
 TFilePrefetch.cxx:111
 TFilePrefetch.cxx:112
 TFilePrefetch.cxx:113
 TFilePrefetch.cxx:114
 TFilePrefetch.cxx:115
 TFilePrefetch.cxx:116
 TFilePrefetch.cxx:117
 TFilePrefetch.cxx:118
 TFilePrefetch.cxx:119
 TFilePrefetch.cxx:120
 TFilePrefetch.cxx:121
 TFilePrefetch.cxx:122
 TFilePrefetch.cxx:123
 TFilePrefetch.cxx:124
 TFilePrefetch.cxx:125
 TFilePrefetch.cxx:126
 TFilePrefetch.cxx:127
 TFilePrefetch.cxx:128
 TFilePrefetch.cxx:129
 TFilePrefetch.cxx:130
 TFilePrefetch.cxx:131
 TFilePrefetch.cxx:132
 TFilePrefetch.cxx:133
 TFilePrefetch.cxx:134
 TFilePrefetch.cxx:135
 TFilePrefetch.cxx:136
 TFilePrefetch.cxx:137
 TFilePrefetch.cxx:138
 TFilePrefetch.cxx:139
 TFilePrefetch.cxx:140
 TFilePrefetch.cxx:141
 TFilePrefetch.cxx:142
 TFilePrefetch.cxx:143
 TFilePrefetch.cxx:144
 TFilePrefetch.cxx:145
 TFilePrefetch.cxx:146
 TFilePrefetch.cxx:147
 TFilePrefetch.cxx:148
 TFilePrefetch.cxx:149
 TFilePrefetch.cxx:150
 TFilePrefetch.cxx:151
 TFilePrefetch.cxx:152
 TFilePrefetch.cxx:153
 TFilePrefetch.cxx:154
 TFilePrefetch.cxx:155
 TFilePrefetch.cxx:156
 TFilePrefetch.cxx:157
 TFilePrefetch.cxx:158
 TFilePrefetch.cxx:159
 TFilePrefetch.cxx:160
 TFilePrefetch.cxx:161
 TFilePrefetch.cxx:162
 TFilePrefetch.cxx:163
 TFilePrefetch.cxx:164
 TFilePrefetch.cxx:165
 TFilePrefetch.cxx:166
 TFilePrefetch.cxx:167
 TFilePrefetch.cxx:168
 TFilePrefetch.cxx:169
 TFilePrefetch.cxx:170
 TFilePrefetch.cxx:171
 TFilePrefetch.cxx:172
 TFilePrefetch.cxx:173
 TFilePrefetch.cxx:174
 TFilePrefetch.cxx:175
 TFilePrefetch.cxx:176
 TFilePrefetch.cxx:177
 TFilePrefetch.cxx:178
 TFilePrefetch.cxx:179
 TFilePrefetch.cxx:180
 TFilePrefetch.cxx:181
 TFilePrefetch.cxx:182
 TFilePrefetch.cxx:183
 TFilePrefetch.cxx:184
 TFilePrefetch.cxx:185
 TFilePrefetch.cxx:186
 TFilePrefetch.cxx:187
 TFilePrefetch.cxx:188
 TFilePrefetch.cxx:189
 TFilePrefetch.cxx:190
 TFilePrefetch.cxx:191
 TFilePrefetch.cxx:192
 TFilePrefetch.cxx:193
 TFilePrefetch.cxx:194
 TFilePrefetch.cxx:195
 TFilePrefetch.cxx:196
 TFilePrefetch.cxx:197
 TFilePrefetch.cxx:198
 TFilePrefetch.cxx:199
 TFilePrefetch.cxx:200
 TFilePrefetch.cxx:201
 TFilePrefetch.cxx:202
 TFilePrefetch.cxx:203
 TFilePrefetch.cxx:204
 TFilePrefetch.cxx:205
 TFilePrefetch.cxx:206
 TFilePrefetch.cxx:207
 TFilePrefetch.cxx:208
 TFilePrefetch.cxx:209
 TFilePrefetch.cxx:210
 TFilePrefetch.cxx:211
 TFilePrefetch.cxx:212
 TFilePrefetch.cxx:213
 TFilePrefetch.cxx:214
 TFilePrefetch.cxx:215
 TFilePrefetch.cxx:216
 TFilePrefetch.cxx:217
 TFilePrefetch.cxx:218
 TFilePrefetch.cxx:219
 TFilePrefetch.cxx:220
 TFilePrefetch.cxx:221
 TFilePrefetch.cxx:222
 TFilePrefetch.cxx:223
 TFilePrefetch.cxx:224
 TFilePrefetch.cxx:225
 TFilePrefetch.cxx:226
 TFilePrefetch.cxx:227
 TFilePrefetch.cxx:228
 TFilePrefetch.cxx:229
 TFilePrefetch.cxx:230
 TFilePrefetch.cxx:231
 TFilePrefetch.cxx:232
 TFilePrefetch.cxx:233
 TFilePrefetch.cxx:234
 TFilePrefetch.cxx:235
 TFilePrefetch.cxx:236
 TFilePrefetch.cxx:237
 TFilePrefetch.cxx:238
 TFilePrefetch.cxx:239
 TFilePrefetch.cxx:240
 TFilePrefetch.cxx:241
 TFilePrefetch.cxx:242
 TFilePrefetch.cxx:243
 TFilePrefetch.cxx:244
 TFilePrefetch.cxx:245
 TFilePrefetch.cxx:246
 TFilePrefetch.cxx:247
 TFilePrefetch.cxx:248
 TFilePrefetch.cxx:249
 TFilePrefetch.cxx:250
 TFilePrefetch.cxx:251
 TFilePrefetch.cxx:252
 TFilePrefetch.cxx:253
 TFilePrefetch.cxx:254
 TFilePrefetch.cxx:255
 TFilePrefetch.cxx:256
 TFilePrefetch.cxx:257
 TFilePrefetch.cxx:258
 TFilePrefetch.cxx:259
 TFilePrefetch.cxx:260
 TFilePrefetch.cxx:261
 TFilePrefetch.cxx:262
 TFilePrefetch.cxx:263
 TFilePrefetch.cxx:264
 TFilePrefetch.cxx:265
 TFilePrefetch.cxx:266
 TFilePrefetch.cxx:267
 TFilePrefetch.cxx:268
 TFilePrefetch.cxx:269
 TFilePrefetch.cxx:270
 TFilePrefetch.cxx:271
 TFilePrefetch.cxx:272
 TFilePrefetch.cxx:273
 TFilePrefetch.cxx:274
 TFilePrefetch.cxx:275
 TFilePrefetch.cxx:276
 TFilePrefetch.cxx:277
 TFilePrefetch.cxx:278
 TFilePrefetch.cxx:279
 TFilePrefetch.cxx:280
 TFilePrefetch.cxx:281
 TFilePrefetch.cxx:282
 TFilePrefetch.cxx:283
 TFilePrefetch.cxx:284
 TFilePrefetch.cxx:285
 TFilePrefetch.cxx:286
 TFilePrefetch.cxx:287
 TFilePrefetch.cxx:288
 TFilePrefetch.cxx:289
 TFilePrefetch.cxx:290
 TFilePrefetch.cxx:291
 TFilePrefetch.cxx:292
 TFilePrefetch.cxx:293
 TFilePrefetch.cxx:294
 TFilePrefetch.cxx:295
 TFilePrefetch.cxx:296
 TFilePrefetch.cxx:297
 TFilePrefetch.cxx:298
 TFilePrefetch.cxx:299
 TFilePrefetch.cxx:300
 TFilePrefetch.cxx:301
 TFilePrefetch.cxx:302
 TFilePrefetch.cxx:303
 TFilePrefetch.cxx:304
 TFilePrefetch.cxx:305
 TFilePrefetch.cxx:306
 TFilePrefetch.cxx:307
 TFilePrefetch.cxx:308
 TFilePrefetch.cxx:309
 TFilePrefetch.cxx:310
 TFilePrefetch.cxx:311
 TFilePrefetch.cxx:312
 TFilePrefetch.cxx:313
 TFilePrefetch.cxx:314
 TFilePrefetch.cxx:315
 TFilePrefetch.cxx:316
 TFilePrefetch.cxx:317
 TFilePrefetch.cxx:318
 TFilePrefetch.cxx:319
 TFilePrefetch.cxx:320
 TFilePrefetch.cxx:321
 TFilePrefetch.cxx:322
 TFilePrefetch.cxx:323
 TFilePrefetch.cxx:324
 TFilePrefetch.cxx:325
 TFilePrefetch.cxx:326
 TFilePrefetch.cxx:327
 TFilePrefetch.cxx:328
 TFilePrefetch.cxx:329
 TFilePrefetch.cxx:330
 TFilePrefetch.cxx:331
 TFilePrefetch.cxx:332
 TFilePrefetch.cxx:333
 TFilePrefetch.cxx:334
 TFilePrefetch.cxx:335
 TFilePrefetch.cxx:336
 TFilePrefetch.cxx:337
 TFilePrefetch.cxx:338
 TFilePrefetch.cxx:339
 TFilePrefetch.cxx:340
 TFilePrefetch.cxx:341
 TFilePrefetch.cxx:342
 TFilePrefetch.cxx:343
 TFilePrefetch.cxx:344
 TFilePrefetch.cxx:345
 TFilePrefetch.cxx:346
 TFilePrefetch.cxx:347
 TFilePrefetch.cxx:348
 TFilePrefetch.cxx:349
 TFilePrefetch.cxx:350
 TFilePrefetch.cxx:351
 TFilePrefetch.cxx:352
 TFilePrefetch.cxx:353
 TFilePrefetch.cxx:354
 TFilePrefetch.cxx:355
 TFilePrefetch.cxx:356
 TFilePrefetch.cxx:357
 TFilePrefetch.cxx:358
 TFilePrefetch.cxx:359
 TFilePrefetch.cxx:360
 TFilePrefetch.cxx:361
 TFilePrefetch.cxx:362
 TFilePrefetch.cxx:363
 TFilePrefetch.cxx:364
 TFilePrefetch.cxx:365
 TFilePrefetch.cxx:366
 TFilePrefetch.cxx:367
 TFilePrefetch.cxx:368
 TFilePrefetch.cxx:369
 TFilePrefetch.cxx:370
 TFilePrefetch.cxx:371
 TFilePrefetch.cxx:372
 TFilePrefetch.cxx:373
 TFilePrefetch.cxx:374
 TFilePrefetch.cxx:375
 TFilePrefetch.cxx:376
 TFilePrefetch.cxx:377
 TFilePrefetch.cxx:378
 TFilePrefetch.cxx:379
 TFilePrefetch.cxx:380
 TFilePrefetch.cxx:381
 TFilePrefetch.cxx:382
 TFilePrefetch.cxx:383
 TFilePrefetch.cxx:384
 TFilePrefetch.cxx:385
 TFilePrefetch.cxx:386
 TFilePrefetch.cxx:387
 TFilePrefetch.cxx:388
 TFilePrefetch.cxx:389
 TFilePrefetch.cxx:390
 TFilePrefetch.cxx:391
 TFilePrefetch.cxx:392
 TFilePrefetch.cxx:393
 TFilePrefetch.cxx:394
 TFilePrefetch.cxx:395
 TFilePrefetch.cxx:396
 TFilePrefetch.cxx:397
 TFilePrefetch.cxx:398
 TFilePrefetch.cxx:399
 TFilePrefetch.cxx:400
 TFilePrefetch.cxx:401
 TFilePrefetch.cxx:402
 TFilePrefetch.cxx:403
 TFilePrefetch.cxx:404
 TFilePrefetch.cxx:405
 TFilePrefetch.cxx:406
 TFilePrefetch.cxx:407
 TFilePrefetch.cxx:408
 TFilePrefetch.cxx:409
 TFilePrefetch.cxx:410
 TFilePrefetch.cxx:411
 TFilePrefetch.cxx:412
 TFilePrefetch.cxx:413
 TFilePrefetch.cxx:414
 TFilePrefetch.cxx:415
 TFilePrefetch.cxx:416
 TFilePrefetch.cxx:417
 TFilePrefetch.cxx:418
 TFilePrefetch.cxx:419
 TFilePrefetch.cxx:420
 TFilePrefetch.cxx:421
 TFilePrefetch.cxx:422
 TFilePrefetch.cxx:423
 TFilePrefetch.cxx:424
 TFilePrefetch.cxx:425
 TFilePrefetch.cxx:426
 TFilePrefetch.cxx:427
 TFilePrefetch.cxx:428
 TFilePrefetch.cxx:429
 TFilePrefetch.cxx:430
 TFilePrefetch.cxx:431
 TFilePrefetch.cxx:432
 TFilePrefetch.cxx:433
 TFilePrefetch.cxx:434
 TFilePrefetch.cxx:435
 TFilePrefetch.cxx:436
 TFilePrefetch.cxx:437
 TFilePrefetch.cxx:438
 TFilePrefetch.cxx:439
 TFilePrefetch.cxx:440
 TFilePrefetch.cxx:441
 TFilePrefetch.cxx:442
 TFilePrefetch.cxx:443
 TFilePrefetch.cxx:444
 TFilePrefetch.cxx:445
 TFilePrefetch.cxx:446
 TFilePrefetch.cxx:447
 TFilePrefetch.cxx:448
 TFilePrefetch.cxx:449
 TFilePrefetch.cxx:450
 TFilePrefetch.cxx:451
 TFilePrefetch.cxx:452
 TFilePrefetch.cxx:453
 TFilePrefetch.cxx:454
 TFilePrefetch.cxx:455
 TFilePrefetch.cxx:456
 TFilePrefetch.cxx:457
 TFilePrefetch.cxx:458
 TFilePrefetch.cxx:459
 TFilePrefetch.cxx:460
 TFilePrefetch.cxx:461
 TFilePrefetch.cxx:462
 TFilePrefetch.cxx:463
 TFilePrefetch.cxx:464
 TFilePrefetch.cxx:465
 TFilePrefetch.cxx:466
 TFilePrefetch.cxx:467
 TFilePrefetch.cxx:468
 TFilePrefetch.cxx:469
 TFilePrefetch.cxx:470
 TFilePrefetch.cxx:471
 TFilePrefetch.cxx:472
 TFilePrefetch.cxx:473
 TFilePrefetch.cxx:474
 TFilePrefetch.cxx:475
 TFilePrefetch.cxx:476
 TFilePrefetch.cxx:477
 TFilePrefetch.cxx:478
 TFilePrefetch.cxx:479
 TFilePrefetch.cxx:480
 TFilePrefetch.cxx:481
 TFilePrefetch.cxx:482
 TFilePrefetch.cxx:483
 TFilePrefetch.cxx:484
 TFilePrefetch.cxx:485
 TFilePrefetch.cxx:486
 TFilePrefetch.cxx:487
 TFilePrefetch.cxx:488
 TFilePrefetch.cxx:489
 TFilePrefetch.cxx:490
 TFilePrefetch.cxx:491
 TFilePrefetch.cxx:492
 TFilePrefetch.cxx:493
 TFilePrefetch.cxx:494
 TFilePrefetch.cxx:495
 TFilePrefetch.cxx:496
 TFilePrefetch.cxx:497
 TFilePrefetch.cxx:498
 TFilePrefetch.cxx:499
 TFilePrefetch.cxx:500
 TFilePrefetch.cxx:501
 TFilePrefetch.cxx:502
 TFilePrefetch.cxx:503
 TFilePrefetch.cxx:504
 TFilePrefetch.cxx:505
 TFilePrefetch.cxx:506
 TFilePrefetch.cxx:507
 TFilePrefetch.cxx:508
 TFilePrefetch.cxx:509
 TFilePrefetch.cxx:510
 TFilePrefetch.cxx:511
 TFilePrefetch.cxx:512
 TFilePrefetch.cxx:513
 TFilePrefetch.cxx:514
 TFilePrefetch.cxx:515
 TFilePrefetch.cxx:516
 TFilePrefetch.cxx:517
 TFilePrefetch.cxx:518
 TFilePrefetch.cxx:519
 TFilePrefetch.cxx:520
 TFilePrefetch.cxx:521
 TFilePrefetch.cxx:522
 TFilePrefetch.cxx:523
 TFilePrefetch.cxx:524
 TFilePrefetch.cxx:525
 TFilePrefetch.cxx:526
 TFilePrefetch.cxx:527
 TFilePrefetch.cxx:528
 TFilePrefetch.cxx:529
 TFilePrefetch.cxx:530
 TFilePrefetch.cxx:531
 TFilePrefetch.cxx:532
 TFilePrefetch.cxx:533
 TFilePrefetch.cxx:534
 TFilePrefetch.cxx:535
 TFilePrefetch.cxx:536
 TFilePrefetch.cxx:537
 TFilePrefetch.cxx:538
 TFilePrefetch.cxx:539
 TFilePrefetch.cxx:540