ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TFileCacheRead.cxx
Go to the documentation of this file.
1 // @(#)root/io:$Id$
2 // Author: Rene Brun 18/05/2006
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, 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 
12 /**
13  \class TFileCacheRead
14  \ingroup IO
15 
16  A cache when reading files over the network.
17 
18  A caching system to speed up network I/O, i.e. when there is
19  no operating system caching support (like the buffer cache for
20  local disk I/O). The cache makes sure that every I/O is done with
21  a (large) fixed length buffer thereby avoiding many small I/O's.
22  Currently the read cache system is used by the classes TNetFile,
23  TXNetFile and TWebFile (via TFile::ReadBuffers()).
24  When processing TTree, TChain, a specialized class TTreeCache that
25  derives from this class is automatically created.
26 */
27 
28 #include "TEnv.h"
29 #include "TFile.h"
30 #include "TFileCacheRead.h"
31 #include "TFileCacheWrite.h"
32 #include "TFilePrefetch.h"
33 #include "TMath.h"
34 
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Default Constructor.
39 
41 {
42  fBufferSizeMin = 0;
43  fBufferSize = 0;
44  fBufferLen = 0;
45  fBytesRead = 0;
46  fNoCacheBytesRead = 0;
47  fBytesReadExtra = 0;
48  fReadCalls = 0;
49  fNoCacheReadCalls = 0;
50  fNseek = 0;
51  fNtot = 0;
52  fNb = 0;
53  fSeekSize = 0;
54  fSeek = 0;
55  fSeekIndex = 0;
56  fSeekSort = 0;
57  fPos = 0;
58  fSeekLen = 0;
59  fSeekSortLen = 0;
60  fSeekPos = 0;
61  fLen = 0;
62  fFile = 0;
63  fBuffer = 0;
64  fIsSorted = kFALSE;
65  fIsTransferred = kFALSE;
66 
67  //values for the second prefetched block
68  fBNseek = 0;
69  fBNtot = 0;
70  fBNb = 0;
71  fBSeekSize = 0;
72  fBSeek = 0;
73  fBSeekSort = 0;
74  fBSeekIndex = 0;
75  fBPos = 0;
76  fBSeekLen = 0;
77  fBSeekSortLen = 0;
78  fBSeekPos = 0;
79  fBLen = 0;
80  fBIsSorted = kFALSE;
81  fBIsTransferred=kFALSE;
82 
83  fAsyncReading = kFALSE;
84  fEnablePrefetching = kFALSE;
85  fPrefetch = 0;
86  fPrefetchedBlocks= 0;
87 }
88 
89 ////////////////////////////////////////////////////////////////////////////////
90 /// Creates a TFileCacheRead data structure.
91 
93  : TObject()
94 {
95  if (buffersize <=10000) fBufferSize = 100000;
96  else fBufferSize = buffersize;
97 
99  fBufferLen = 0;
100  fBytesRead = 0;
101  fNoCacheBytesRead = 0;
102  fBytesReadExtra = 0;
103  fReadCalls = 0;
104  fNoCacheReadCalls = 0;
105  fNseek = 0;
106  fNtot = 0;
107  fNb = 0;
108  fSeekSize = 10000;
109  fSeek = new Long64_t[fSeekSize];
110  fSeekIndex = new Int_t[fSeekSize];
112  fPos = new Long64_t[fSeekSize];
113  fSeekLen = new Int_t[fSeekSize];
115  fSeekPos = new Int_t[fSeekSize];
116  fLen = new Int_t[fSeekSize];
117  fFile = file;
118 
119  //initialisation for the second block
120  fBNseek = 0;
121  fBNtot = 0;
122  fBNb = 0;
123  fBSeekSize = 10000;
124  fBSeek = new Long64_t[fBSeekSize];
127  fBPos = new Long64_t[fBSeekSize];
128  fBSeekLen = new Int_t[fBSeekSize];
130  fBSeekPos = new Int_t[fBSeekSize];
131  fBLen = new Int_t[fBSeekSize];
132 
133  fBuffer = 0;
134  fPrefetch = 0;
135  fPrefetchedBlocks = 0;
136 
137  //initialise the prefetch object and set the cache directory
138  // start the thread only if the file is not local
139  fEnablePrefetching = gEnv->GetValue("TFile.AsyncPrefetching", 0);
140 
141  if (fEnablePrefetching && strcmp(file->GetEndpointUrl()->GetProtocol(), "file")){
143  }
144  else { //disable the async pref for local files
146  }
147 
148  fIsSorted = kFALSE;
150  fBIsSorted = kFALSE;
152 
153  if (file) file->SetCacheRead(this, tree);
154 }
155 
156 ////////////////////////////////////////////////////////////////////////////////
157 /// Destructor.
158 
160 {
162  delete [] fSeek;
163  delete [] fSeekIndex;
164  delete [] fSeekSort;
165  delete [] fPos;
166  delete [] fSeekLen;
167  delete [] fSeekSortLen;
168  delete [] fSeekPos;
169  delete [] fLen;
170  if (fBuffer)
171  delete [] fBuffer;
172  delete [] fBSeek;
173  delete [] fBSeekIndex;
174  delete [] fBSeekSort;
175  delete [] fBPos;
176  delete [] fBSeekLen;
177  delete [] fBSeekSortLen;
178  delete [] fBSeekPos;
179  delete [] fBLen;
180 }
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 /// Close out any threads or asynchronous fetches used by the underlying
184 /// implementation.
185 /// This is called by TFile::Close to prevent usage of the file handles
186 /// after the closing of the file.
187 
188 void TFileCacheRead::Close(Option_t * /* opt = "" */)
189 {
190  if (fPrefetch) {
191  delete fPrefetch;
192  fPrefetch = 0;
193  }
194 
195 }
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// Add block of length len at position pos in the list of blocks to
199 /// be prefetched. If pos <= 0 the current blocks (if any) are reset.
200 
202 {
203  fIsSorted = kFALSE;
205  if (pos <= 0) {
206  fNseek = 0;
207  fNtot = 0;
208  return;
209  }
210  if (fNseek >= fSeekSize) {
211  //reallocate buffers
212  fSeekSize *= 2;
213  Long64_t *aSeek = new Long64_t[fSeekSize];
214  Int_t *aSeekIndex = new Int_t[fSeekSize];
215  Long64_t *aSeekSort = new Long64_t[fSeekSize];
216  Long64_t *aPos = new Long64_t[fSeekSize];
217  Int_t *aSeekLen = new Int_t[fSeekSize];
218  Int_t *aSeekSortLen = new Int_t[fSeekSize];
219  Int_t *aSeekPos = new Int_t[fSeekSize];
220  Int_t *aLen = new Int_t[fSeekSize];
221  for (Int_t i=0;i<fNseek;i++) {
222  aSeek[i] = fSeek[i];
223  aSeekIndex[i] = fSeekIndex[i];
224  aSeekSort[i] = fSeekSort[i];
225  aPos[i] = fPos[i];
226  aSeekLen[i] = fSeekLen[i];
227  aSeekSortLen[i] = fSeekSortLen[i];
228  aSeekPos[i] = fSeekPos[i];
229  aLen[i] = fLen[i];
230  }
231  delete [] fSeek;
232  delete [] fSeekIndex;
233  delete [] fSeekSort;
234  delete [] fPos;
235  delete [] fSeekLen;
236  delete [] fSeekSortLen;
237  delete [] fSeekPos;
238  delete [] fLen;
239  fSeek = aSeek;
240  fSeekIndex = aSeekIndex;
241  fSeekSort = aSeekSort;
242  fPos = aPos;
243  fSeekLen = aSeekLen;
244  fSeekSortLen = aSeekSortLen;
245  fSeekPos = aSeekPos;
246  fLen = aLen;
247  }
248 
249  fSeek[fNseek] = pos;
250  fSeekLen[fNseek] = len;
251  fNseek++;
252  fNtot += len;
253 }
254 
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 
259  //add a new element and increase the size if necessary
260  fBIsSorted = kFALSE;
261  if (pos <= 0) {
262  fBNseek = 0;
263  fBNtot = 0;
264  return;
265  }
266  if (fBNseek >= fBSeekSize) {
267  //reallocate buffers
268  fBSeekSize *= 2;
269  Long64_t *aSeek = new Long64_t[fBSeekSize];
270  Int_t *aSeekIndex = new Int_t[fBSeekSize];
271  Long64_t *aSeekSort = new Long64_t[fBSeekSize];
272  Long64_t *aPos = new Long64_t[fBSeekSize];
273  Int_t *aSeekLen = new Int_t[fBSeekSize];
274  Int_t *aSeekSortLen = new Int_t[fBSeekSize];
275  Int_t *aSeekPos = new Int_t[fBSeekSize];
276  Int_t *aLen = new Int_t[fBSeekSize];
277  for (Int_t i=0;i<fBNseek;i++) {
278  aSeek[i] = fBSeek[i];
279  aSeekIndex[i] = fBSeekIndex[i];
280  aSeekSort[i] = fBSeekSort[i];
281  aPos[i] = fBPos[i];
282  aSeekLen[i] = fBSeekLen[i];
283  aSeekSortLen[i] = fBSeekSortLen[i];
284  aSeekPos[i] = fBSeekPos[i];
285  aLen[i] = fBLen[i];
286  }
287  delete [] fBSeek;
288  delete [] fBSeekIndex;
289  delete [] fBSeekSort;
290  delete [] fBPos;
291  delete [] fBSeekLen;
292  delete [] fBSeekSortLen;
293  delete [] fBSeekPos;
294  delete [] fBLen;
295  fBSeek = aSeek;
296  fBSeekIndex = aSeekIndex;
297  fBSeekSort = aSeekSort;
298  fBPos = aPos;
299  fBSeekLen = aSeekLen;
300  fBSeekSortLen = aSeekSortLen;
301  fBSeekPos = aSeekPos;
302  fBLen = aLen;
303  }
304 
305  fBSeek[fBNseek] = pos;
306  fBSeekLen[fBNseek] = len;
307  fBNseek++;
308  fBNtot += len;
309 }
310 
311 
312 ////////////////////////////////////////////////////////////////////////////////
313 /// Print cache statistics.
314 ///
315 /// The format is:
316 /// ******TreeCache statistics for file: cms2.root ******
317 /// Reading............................: 72761843 bytes in 7 transactions
318 /// Readahead..........................: 256000 bytes with overhead = 0 bytes
319 /// Average transaction................: 10394.549000 Kbytes
320 /// Number of blocks in current cache..: 210, total size: 6280352
321 ///
322 /// If option = "a" the list of blocks in the cache is printed
323 /// NB: this function is automatically called by TTreeCache::Print
324 
325 void TFileCacheRead::Print(Option_t *option) const
326 {
327  TString opt = option;
328  opt.ToLower();
329  printf("Cached Reading.....................: %lld bytes in %d transactions\n",this->GetBytesRead(), this->GetReadCalls());
330  printf("Reading............................: %lld bytes in %d uncached transactions\n",this->GetNoCacheBytesRead(), this->GetNoCacheReadCalls());
331  printf("Readahead..........................: %d bytes with overhead = %lld bytes\n",TFile::GetReadaheadSize(),this->GetBytesReadExtra());
332  printf("Average transaction................: %f Kbytes\n",0.001*Double_t(this->GetBytesRead())/Double_t(this->GetReadCalls()));
333  printf("Number of blocks in current cache..: %d, total size: %d\n",fNseek,fNtot);
334  if (fPrefetch){
335  printf("Prefetching .......................: %lli blocks\n", fPrefetchedBlocks);
336  printf("Prefetching Wait Time..............: %f seconds\n", fPrefetch->GetWaitTime() / 1e+6);
337  }
338 
339  if (!opt.Contains("a")) return;
340  for (Int_t i=0;i<fNseek;i++) {
341  if (fIsSorted && !opt.Contains("s")) {
342  printf("block: %5d, from: %lld to %lld, len = %d bytes\n",i,fSeekSort[i],fSeekSort[i]+fSeekSortLen[i],fSeekSortLen[i]);
343  } else {
344  printf("block: %5d, from: %lld to %lld, len = %d bytes\n",i,fSeek[i],fSeek[i]+fSeekLen[i],fSeekLen[i]);
345  }
346  }
347  printf ("Number of long buffers = %d\n",fNb);
348  for (Int_t j=0;j<fNb;j++) {
349  printf("fPos[%d] = %lld, fLen = %d\n",j,fPos[j],fLen[j]);
350  }
351 }
352 
353 ////////////////////////////////////////////////////////////////////////////////
354 /// Read buffer at position pos.
355 ///
356 /// If pos is in the list of prefetched blocks read from fBuffer,
357 /// otherwise need to make a normal read from file. Returns -1 in case of
358 /// read error, 0 in case not in cache, 1 in case read from cache.
359 
361 {
362  Long64_t fileBytesRead0 = fFile->GetBytesRead();
363  Long64_t fileBytesReadExtra0 = fFile->GetBytesReadExtra();
364  Int_t fileReadCalls0 = fFile->GetReadCalls();
365 
366  Int_t loc = -1;
367  Int_t rc = ReadBufferExt(buf, pos, len, loc);
368 
369  fBytesRead += fFile->GetBytesRead() - fileBytesRead0;
370  fBytesReadExtra += fFile->GetBytesReadExtra() - fileBytesReadExtra0;
371  fReadCalls += fFile->GetReadCalls() - fileReadCalls0;
372 
373  return rc;
374 }
375 
376 ////////////////////////////////////////////////////////////////////////////////
377 
379 {
380  if (fEnablePrefetching)
381  return ReadBufferExtPrefetch(buf, pos, len, loc);
382  else
383  return ReadBufferExtNormal(buf, pos, len, loc);
384 }
385 
386 
387 ////////////////////////////////////////////////////////////////////////////////
388 ///prefetch the first block
389 
391 {
392  if (fNseek > 0 && !fIsSorted) {
393  Sort();
394  loc = -1;
398  }
399 
400  //try to prefetch the second block
401  if (fBNseek > 0 && !fBIsSorted) {
402  SecondSort();
403  loc = -1;
406  }
407 
408  // in case we are writing and reading to/from this file, we must check
409  // if this buffer is in the write cache (not yet written to the file)
410  if (TFileCacheWrite *cachew = fFile->GetCacheWrite()) {
411  if (cachew->ReadBuffer(buf,pos,len) == 0) {
412  fFile->SetOffset(pos+len);
413  return 1;
414  }
415  }
416 
417  // try to prefetch from the first block
418  if (loc < 0) {
420  }
421 
422  if (loc >= 0 && loc < fNseek && pos == fSeekSort[loc]) {
423  if (buf && fPrefetch){
424  // prefetch with the new method
425  fPrefetch->ReadBuffer(buf, pos, len);
426  return 1;
427  }
428  }
429  else if (buf && fPrefetch){
430  // try to preferch from the second block
432 
433  if (loc >= 0 && loc < fBNseek && pos == fBSeekSort[loc]){
434  if (fPrefetch->ReadBuffer(buf, pos, len)) {
435  return 1;
436  }
437  }
438  }
439 
440  return 0;
441 }
442 
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 /// Base function for ReadBuffer.
446 ///
447 /// Also gives out the position of the block in the internal buffer.
448 /// This helps TTreeCacheUnzip to avoid doing twice the binary search.
449 
451 {
452  if (fNseek > 0 && !fIsSorted) {
453  Sort();
454  loc = -1;
455 
456  // If ReadBufferAsync is not supported by this implementation...
457  if (!fAsyncReading) {
458  // Then we use the vectored read to read everything now
460  return -1;
461  }
463  } else {
464  // In any case, we'll start to request the chunks.
465  // This implementation simply reads all the chunks in advance
466  // in the async way.
467 
468  // Use the async readv instead of single reads
469  fFile->ReadBuffers(0, 0, 0, 0); //Clear the XrdClient cache
470  if (fFile->ReadBuffers(0,fPos,fLen,fNb)) {
471  return -1;
472  }
474  }
475  }
476 
477  // in case we are writing and reading to/from this file, we much check
478  // if this buffer is in the write cache (not yet written to the file)
479  if (TFileCacheWrite *cachew = fFile->GetCacheWrite()) {
480  if (cachew->ReadBuffer(buf,pos,len) == 0) {
481  fFile->SetOffset(pos+len);
482  return 1;
483  }
484  }
485 
486  // If asynchronous reading is supported by this implementation...
487  if (fAsyncReading) {
488 
489  // Now we dont have to look for it in the local buffer
490  // if it's async, we expect that the communication library
491  // will handle it more efficiently than we can do here
492 
493  Int_t retval;
494  if (loc < 0)
496 
497  // We use the internal list just to notify if the list is to be reconstructed
498  if (loc >= 0 && loc < fNseek && pos == fSeekSort[loc]) {
499  // Block found, the caller will get it
500 
501  if (buf) {
502  // disable cache to avoid infinite recursion
503  if (fFile->ReadBuffer(buf, pos, len)) {
504  return -1;
505  }
506  fFile->SetOffset(pos+len);
507  }
508 
509  retval = 1;
510  } else {
511  // Block not found in the list, we report it as a miss
512  retval = 0;
513  }
514 
515  if (gDebug > 0)
516  Info("ReadBuffer","pos=%lld, len=%d, retval=%d, loc=%d, "
517  "fseekSort[loc]=%lld, fSeekLen[loc]=%d",
518  pos, len, retval, loc, fSeekSort[loc], fSeekLen[loc]);
519 
520  return retval;
521  } else {
522 
523  if (loc < 0)
525 
526  if (loc >= 0 && loc <fNseek && pos == fSeekSort[loc]) {
527  if (buf) {
528  memcpy(buf,&fBuffer[fSeekPos[loc]],len);
529  fFile->SetOffset(pos+len);
530  }
531  return 1;
532  }
533  }
534 
535  return 0;
536 }
537 
538 ////////////////////////////////////////////////////////////////////////////////
539 /// Set the file using this cache and reset the current blocks (if any).
540 
542 {
543  fFile = file;
544 
545  if (fAsyncReading) {
546  // If asynchronous reading is not supported by this TFile specialization
547  // we use sync primitives, hence we need the local buffer
548  if (file && file->ReadBufferAsync(0, 0)) {
550  fBuffer = new char[fBufferSize];
551  }
552  }
553 
554  if (action == TFile::kDisconnect)
555  Prefetch(0,0);
556 
557  if (fPrefetch) {
558  if (action == TFile::kDisconnect)
559  SecondPrefetch(0, 0);
560  fPrefetch->SetFile(file);
561  }
562 }
563 
564 ////////////////////////////////////////////////////////////////////////////////
565 /// Sort buffers to be prefetched in increasing order of positions.
566 /// Merge consecutive blocks if necessary.
567 
569 {
570  if (!fNseek) return;
572  Int_t i;
573  Int_t nb = 0;
574  Int_t effectiveNseek = 0;
575  for (i=0;i<fNseek;i++) {
576  // Skip duplicates
577  Int_t ind = fSeekIndex[i];
578  if (effectiveNseek!=0 && fSeek[ind]==fSeekSort[effectiveNseek-1])
579  {
580  if (fSeekSortLen[effectiveNseek-1] < fSeekLen[ind]) {
581  fSeekSortLen[effectiveNseek-1] = fSeekLen[ind];
582  }
583  continue;
584  }
585  fSeekSort[effectiveNseek] = fSeek[ind];
586  fSeekSortLen[effectiveNseek] = fSeekLen[ind];
587  ++effectiveNseek;
588  }
589  fNseek = effectiveNseek;
590  if (fNtot > fBufferSizeMin) {
591  fBufferSize = fNtot + 100;
592  delete [] fBuffer;
593  fBuffer = 0;
594  // If ReadBufferAsync is not supported by this implementation
595  // it means that we are using sync primitives, hence we need the local buffer
596  if (!fAsyncReading)
597  fBuffer = new char[fBufferSize];
598  }
599  fPos[0] = fSeekSort[0];
600  fLen[0] = fSeekSortLen[0];
601  fSeekPos[0] = 0;
602  for (i=1;i<fNseek;i++) {
603  fSeekPos[i] = fSeekPos[i-1] + fSeekSortLen[i-1];
604  //in the test below 16 MBytes is pure empirirical and may depend on the file system.
605  //increasing this number must be done with care, as it may increase
606  //the job real time (mismatch with OS buffers)
607  if ((fSeekSort[i] != fSeekSort[i-1]+fSeekSortLen[i-1]) ||
608  (fLen[nb] > 16000000)) {
609  nb++;
610  fPos[nb] = fSeekSort[i];
611  fLen[nb] = fSeekSortLen[i];
612  } else {
613  fLen[nb] += fSeekSortLen[i];
614  }
615  }
616  fNb = nb+1;
617  fIsSorted = kTRUE;
618 }
619 
620 
621 ////////////////////////////////////////////////////////////////////////////////
622 /// Sort buffers to be prefetched in increasing order of positions.
623 ///
624 /// Merge consecutive blocks if necessary.
625 
627 {
628  if (!fBNseek) return;
630  Int_t i;
631  Int_t nb = 0;
632  Int_t effectiveNseek = 0;
633  for (i=0;i<fBNseek;i++) {
634  // Skip duplicates
635  Int_t ind = fBSeekIndex[i];
636  if (effectiveNseek!=0 && fBSeek[ind]==fBSeekSort[effectiveNseek-1])
637  {
638  if (fBSeekSortLen[effectiveNseek-1] < fBSeekLen[ind]) {
639  fBSeekSortLen[effectiveNseek-1] = fBSeekLen[ind];
640  }
641  continue;
642  }
643  fBSeekSort[effectiveNseek] = fBSeek[ind];
644  fBSeekSortLen[effectiveNseek] = fBSeekLen[ind];
645  ++effectiveNseek;
646  }
647  fBNseek = effectiveNseek;
648  if (fBNtot > fBufferSizeMin) {
649  fBufferSize = fBNtot + 100;
650  delete [] fBuffer;
651  fBuffer = 0;
652  // If ReadBufferAsync is not supported by this implementation
653  // it means that we are using sync primitives, hence we need the local buffer
654  if (!fAsyncReading)
655  fBuffer = new char[fBufferSize];
656  }
657  fBPos[0] = fBSeekSort[0];
658  fBLen[0] = fBSeekSortLen[0];
659  fBSeekPos[0] = 0;
660  for (i=1;i<fBNseek;i++) {
661  fBSeekPos[i] = fBSeekPos[i-1] + fBSeekSortLen[i-1];
662  //in the test below 16 MBytes is pure empirirical and may depend on the file system.
663  //increasing this number must be done with care, as it may increase
664  //the job real time (mismatch with OS buffers)
665  if ((fBSeekSort[i] != fBSeekSort[i-1]+fBSeekSortLen[i-1]) ||
666  (fBLen[nb] > 16000000)) {
667  nb++;
668  fBPos[nb] = fBSeekSort[i];
669  fBLen[nb] = fBSeekSortLen[i];
670  } else {
671  fBLen[nb] += fBSeekSortLen[i];
672  }
673  }
674  fBNb = nb+1;
675  fBIsSorted = kTRUE;
676 }
677 
678 ////////////////////////////////////////////////////////////////////////////////
679 
681  return this->fPrefetch;
682 }
683 
684 
685 ////////////////////////////////////////////////////////////////////////////////
686 
688 {
689  if ( fEnablePrefetching && fPrefetch ) {
691  }
692 }
693 
694 
695 ////////////////////////////////////////////////////////////////////////////////
696 /// Sets the buffer size.
697 ///
698 /// If the current prefetch list is too large to fit in
699 /// the new buffer some or all of the prefetch blocks are dropped. The
700 /// requested buffersize must be greater than zero.
701 /// Return values:
702 /// - 0 if the prefetch block lists remain unchanged
703 /// - 1 if some or all blocks have been removed from the prefetch list
704 /// - -1 on error
705 
707 {
708  if (buffersize <= 0) return -1;
709  if (buffersize <=10000) buffersize = 100000;
710 
711  if (buffersize == fBufferSize) {
712  fBufferSizeMin = buffersize;
713  return 0;
714  }
715 
716  Bool_t inval = kFALSE;
717 
718  // the cached data is too large to fit in the new buffer size mark data unavailable
719  if (fNtot > buffersize) {
720  Prefetch(0, 0);
721  inval = kTRUE;
722  }
723  if (fBNtot > buffersize) {
724  SecondPrefetch(0, 0);
725  inval = kTRUE;
726  }
727 
728  char *np = 0;
730  char *pres = 0;
731  if (fIsTransferred) {
732  // will need to preserve buffer data
733  pres = fBuffer;
734  fBuffer = 0;
735  }
736  delete [] fBuffer;
737  fBuffer = 0;
738  np = new char[buffersize];
739  if (pres) {
740  memcpy(np, pres, fNtot);
741  }
742  delete [] pres;
743  }
744 
745  delete [] fBuffer;
746  fBuffer = np;
747  fBufferSizeMin = buffersize;
748  fBufferSize = buffersize;
749 
750  if (inval) {
751  return 1;
752  }
753 
754  return 0;
755 }
756 
757 
758 ////////////////////////////////////////////////////////////////////////////////
759 /// Set the prefetching mode of this file.
760 ///
761 /// If 'setPrefetching', enable the asynchronous prefetching
762 /// (using TFilePrefetch) and if the gEnv and rootrc
763 /// variable Cache.Directory is set, also enable the local
764 /// caching of the prefetched blocks.
765 /// if 'setPrefetching', the old prefetcher is enabled is
766 /// the gEnv and rootrc variable is TFile.AsyncReading
767 
769 {
770  SetEnablePrefetchingImpl(setPrefetching);
771 }
772 
773 ////////////////////////////////////////////////////////////////////////////////
774 /// TFileCacheRead implementation of SetEnablePrefetching.
775 ///
776 /// This function is called from the constructor and should not be virtual.
777 
779 {
780  fEnablePrefetching = setPrefetching;
781 
782  if (!fPrefetch && fEnablePrefetching) {
784  const char* cacheDir = gEnv->GetValue("Cache.Directory", "");
785  if (strcmp(cacheDir, ""))
786  if (!fPrefetch->SetCache((char*) cacheDir))
787  fprintf(stderr, "Error while trying to set the cache directory: %s.\n", cacheDir);
788  if (fPrefetch->ThreadStart()){
789  fprintf(stderr,"Error stating prefetching thread. Disabling prefetching.\n");
790  fEnablePrefetching = 0;
791  }
792  } else if (fPrefetch && !fEnablePrefetching) {
794  fPrefetch = NULL;
795  }
796 
797  //environment variable used to switch to the new method of reading asynchronously
798  if (fEnablePrefetching) {
800  }
801  else {
802  fAsyncReading = gEnv->GetValue("TFile.AsyncReading", 0);
803  if (fAsyncReading) {
804  // Check if asynchronous reading is supported by this TFile specialization
806  if (fFile && !(fFile->ReadBufferAsync(0, 0)))
808  }
809  if (!fAsyncReading && fBuffer == 0) {
810  // we use sync primitives, hence we need the local buffer
811  fBuffer = new char[fBufferSize];
812  }
813  }
814 }
815 
Int_t fNtot
Total size of prefetched blocks.
Long64_t * fBSeek
[fBNseek]
TFile * fFile
Pointer to file.
long long Long64_t
Definition: RtypesCore.h:69
char * fBuffer
[fBufferSize] buffer of contiguous prefetched blocks
virtual Long64_t GetBytesRead() const
virtual void SetEnablePrefetching(Bool_t setPrefetching=kFALSE)
Set the prefetching mode of this file.
A cache when reading files over the network.
const char Option_t
Definition: RtypesCore.h:62
virtual void SecondSort()
Sort buffers to be prefetched in increasing order of positions.
void SetEnablePrefetchingImpl(Bool_t setPrefetching=kFALSE)
TFileCacheRead implementation of SetEnablePrefetching.
virtual void SetCacheRead(TFileCacheRead *cache, TObject *tree=0, ECacheAction action=kDisconnect)
Set a pointer to the read cache.
Definition: TFile.cxx:2177
virtual void SetOffset(Long64_t offset, ERelativeTo pos=kBeg)
Set position from where to start reading.
Definition: TFile.cxx:2064
Int_t fBufferSize
Allocated size of fBuffer (at a given time)
const char * GetProtocol() const
Definition: TUrl.h:73
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:45
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Read a buffer from the file.
Definition: TFile.cxx:1596
Long64_t fPrefetchedBlocks
Number of blocks prefetched.
virtual Int_t GetReadCalls() const
Long64_t GetWaitTime()
Return the time spent wating for buffer to be read in microseconds.
virtual void Sort()
Sort buffers to be prefetched in increasing order of positions.
virtual const TUrl * GetEndpointUrl() const
Definition: TFile.h:195
Basic string class.
Definition: TString.h:137
Bool_t fIsSorted
True if fSeek array is sorted.
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1075
virtual void Prefetch(Long64_t pos, Int_t len)
Add block of length len at position pos in the list of blocks to be prefetched.
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
Int_t fReadCalls
Number of read calls for this cache.
Int_t ThreadStart()
Used to start the consumer thread.
virtual ~TFileCacheRead()
Destructor.
virtual TFilePrefetch * GetPrefetchObj()
#define SafeDelete(p)
Definition: RConfig.h:436
virtual void SecondPrefetch(Long64_t, Int_t)
Int_t * fBSeekPos
[fBNseek]
Long64_t * fBSeekSort
[fBNseek]
Int_t * fSeekLen
[fNseek] Length of buffers to be prefetched
Bool_t fIsTransferred
True when fBuffer contains something valid.
Int_t fBufferLen
Current buffer length (<= fBufferSize)
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Definition: TMath.h:1002
tuple np
Definition: multifit.py:30
Long64_t fBytesRead
Number of bytes read for this cache.
virtual Long64_t GetNoCacheBytesRead() const
void SetFile(TFile *)
Change the file.
Int_t * fBSeekSortLen
[fBNseek]
virtual Int_t ReadBufferExt(char *buf, Long64_t pos, Int_t len, Int_t &loc)
Int_t * fBSeekIndex
[fBNseek]
virtual Int_t ReadBufferExtNormal(char *buf, Long64_t pos, Int_t len, Int_t &loc)
Base function for ReadBuffer.
Int_t fSeekSize
Allocated size of fSeek.
Int_t * fSeekIndex
[fNseek] sorted index table of fSeek
void WaitFinishPrefetch()
Killing the async prefetching thread.
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
virtual void Print(Option_t *option="") const
Print cache statistics.
virtual void SetFile(TFile *file, TFile::ECacheAction action=TFile::kDisconnect)
Set the file using this cache and reset the current blocks (if any).
virtual Int_t GetNoCacheReadCalls() const
Bool_t ReadBuffer(char *, Long64_t, Int_t)
Return a prefetched element.
Long64_t fBytesReadExtra
Number of extra bytes (overhead) read by the readahead buffer.
Long64_t fNoCacheBytesRead
Number of bytes read by basket to fill cached tree.
Bool_t fAsyncReading
virtual Int_t SetBufferSize(Int_t buffersize)
Sets the buffer size.
Long64_t * fPos
[fNb] start of long buffers
virtual Int_t GetReadCalls() const
Definition: TFile.h:204
Int_t * fBSeekLen
[fBNseek]
virtual Long64_t GetBytesRead() const
Definition: TFile.h:201
Int_t fNb
Number of long buffers.
ClassImp(TFileCacheRead) TFileCacheRead
Default Constructor.
Int_t fBufferSizeMin
Original size of fBuffer.
tuple tree
Definition: tree.py:24
tuple file
Definition: fildir.py:20
double Double_t
Definition: RtypesCore.h:55
static Int_t GetReadaheadSize()
Static function returning the readahead buffer size.
Definition: TFile.cxx:4344
virtual void WaitFinishPrefetch()
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
The prefetching mechanism uses two classes (TFilePrefetch and TFPBlock) to prefetch in advance a bloc...
Definition: TFilePrefetch.h:51
Int_t * fSeekPos
[fNseek] Position of sorted blocks in fBuffer
Mother of all ROOT objects.
Definition: TObject.h:58
Long64_t * fSeekSort
[fNseek] Position on file of buffers to be prefetched (sorted)
virtual Int_t ReadBufferExtPrefetch(char *buf, Long64_t pos, Int_t len, Int_t &loc)
prefetch the first block
Bool_t fEnablePrefetching
reading by prefetching asynchronously
TFilePrefetch * fPrefetch
! Object that does the asynchronous reading in another thread
virtual Long64_t GetBytesReadExtra() const
Bool_t SetCache(const char *)
Set the path of the cache directory.
Int_t * fLen
[fNb] Length of long buffers
virtual Bool_t ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Read the nbuf blocks described in arrays pos and len.
Definition: TFile.cxx:1647
Long64_t * fSeek
[fNseek] Position on file of buffers to be prefetched
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
void ReadBlock(Long64_t *, Int_t *, Int_t)
Create a TFPBlock object or recycle one and add it to the prefetchBlocks list.
#define NULL
Definition: Rtypes.h:82
Long64_t * fBPos
[fBNb]
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
virtual Int_t ReadBuffer(char *buf, Long64_t pos, Int_t len)
Read buffer at position pos.
Int_t * fBLen
[fBNb]
virtual void Close(Option_t *option="")
Close out any threads or asynchronous fetches used by the underlying implementation.
const Bool_t kTRUE
Definition: Rtypes.h:91
Int_t * fSeekSortLen
[fNseek] Length of buffers to be prefetched (sorted)
Bool_t fBIsTransferred
TFileCacheWrite * GetCacheWrite() const
Return a pointer to the current write cache.
Definition: TFile.cxx:1213
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMath.h:944
Int_t fNoCacheReadCalls
Number of read calls by basket to fill cached tree.
virtual Long64_t GetBytesReadExtra() const
Definition: TFile.h:202
A cache when writing files over the network.
virtual Bool_t ReadBufferAsync(Long64_t offs, Int_t len)
Definition: TFile.cxx:4955
Int_t fNseek
Number of blocks to be prefetched.
ECacheAction
TTreeCache flushing semantics.
Definition: TFile.h:57