XrdClientReadCache.hh

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////
00002 //                                                                      //
00003 // XrdClientReadCache                                                   //
00004 //                                                                      //
00005 // Author: Fabrizio Furano (INFN Padova, 2006)                          //
00006 //                                                                      //
00007 // Classes to handle cache reading and cache placeholders               //
00008 //                                                                      //
00009 //////////////////////////////////////////////////////////////////////////
00010 
00011 //       $Id: XrdClientReadCache.hh 31508 2009-12-02 19:11:01Z brun $
00012 
00013 #ifndef XRD_READCACHE_H
00014 #define XRD_READCACHE_H
00015 
00016 #include "XrdSys/XrdSysHeaders.hh"
00017 #include "XrdClient/XrdClientInputBuffer.hh"
00018 #include "XrdClient/XrdClientMessage.hh"
00019 #include "XrdClient/XrdClientVector.hh"
00020 #include "XrdClient/XrdClientConst.hh"
00021 
00022 
00023 //
00024 // XrdClientReadCacheItem
00025 //
00026 // An item is nothing more than an interval of bytes taken from a file.
00027 // Extremes are included.
00028 // Since a cache object is to be associated to a single instance
00029 // of TXNetFile, we do not have to keep here any filehandle
00030 //
00031 
00032 class XrdClientReadCacheItem {
00033 private:
00034     // A placeholder block is a "fake block" used to mark outstanding data
00035     bool             fIsPlaceholder;  
00036 
00037     long long        fBeginOffset;    // Offset of the first byte of data
00038     void             *fData;
00039     long long        fEndOffset;      // Offset of the last byte of data
00040     long             fTimestampTicks; // timestamp updated each time it's referenced
00041 
00042 public:
00043     XrdClientReadCacheItem(const void *buffer, long long begin_offs, 
00044                            long long end_offs, long long ticksnow,
00045                            bool placeholder=false);
00046     ~XrdClientReadCacheItem();
00047 
00048     inline long long BeginOffset() { return fBeginOffset; }
00049     inline long long EndOffset() { return fEndOffset; }
00050 
00051     // Is this obj contained in the given interval (which is going to be inserted) ?
00052     inline bool   ContainedInInterval(long long begin_offs, long long end_offs) {
00053         return ( (end_offs >= begin_offs) &&
00054                  (fBeginOffset >= begin_offs) &&
00055                  (fEndOffset <= end_offs) );
00056     }
00057 
00058     // Does this obj contain the given interval (which is going to be requested) ?
00059     inline bool   ContainsInterval(long long begin_offs, long long end_offs) {
00060         return ( (end_offs > begin_offs) &&
00061                  (fBeginOffset <= begin_offs) && (fEndOffset >= end_offs) );
00062     }
00063 
00064     // Are the two intervals intersecting in some way?
00065     inline bool  IntersectInterval(long long begin_offs, long long end_offs) {
00066       if ( ContainsOffset( begin_offs ) || ContainsOffset( end_offs ) ) return true;
00067       if ( (fBeginOffset >= begin_offs) && (fBeginOffset <= end_offs) ) return true;
00068       return false;
00069     }
00070 
00071 
00072     inline bool ContainsOffset(long long offs) {
00073         return (fBeginOffset <= offs) && (fEndOffset >= offs);
00074     }
00075 
00076     void *GetData() { return fData; }
00077     
00078     // Get the requested interval, if possible
00079     inline bool   GetInterval(const void *buffer, long long begin_offs, 
00080                               long long end_offs) {
00081         if (!ContainsInterval(begin_offs, end_offs))
00082             return FALSE;
00083         memcpy((void *)buffer, ((char *)fData)+(begin_offs - fBeginOffset),
00084                end_offs - begin_offs + 1);
00085         return TRUE;
00086     }
00087 
00088     // Get as many bytes as possible, starting from the beginning of the given
00089     // interval
00090     inline long   GetPartialInterval(const void *buffer, long long begin_offs,
00091                                      long long end_offs) {
00092 
00093         long long b = -1, e, l;
00094 
00095         if (begin_offs > end_offs) return 0;
00096 
00097         // Try to set the starting point, if contained in the given interval
00098         if ( (begin_offs >= fBeginOffset) &&
00099              (begin_offs <= fEndOffset) )
00100             b = begin_offs;
00101 
00102         if (b < 0) return 0;
00103 
00104         // The starting point is in the interval. Let's get the minimum endpoint
00105         e = xrdmin(end_offs, fEndOffset);
00106 
00107         l = e - b + 1;
00108 
00109         if (buffer && fData)
00110             memcpy((void *)buffer, ((char *)fData)+(b - fBeginOffset), l);
00111 
00112         return l;
00113     }
00114 
00115     inline long long GetTimestampTicks() { return(fTimestampTicks); }
00116 
00117     inline bool IsPlaceholder() { return fIsPlaceholder; }
00118 
00119     long Size() { return (fEndOffset - fBeginOffset + 1); }
00120 
00121     inline void     Touch(long long ticksnow) { fTimestampTicks = ticksnow; }
00122 
00123     bool Pinned;
00124 };
00125 
00126 //
00127 // XrdClientReadCache
00128 //
00129 // The content of the cache. Not cache blocks, but
00130 // variable length Items
00131 //
00132 typedef XrdClientVector<XrdClientReadCacheItem *> ItemVect;
00133 
00134 // A cache interval, extremes included
00135 struct XrdClientCacheInterval {
00136     long long beginoffs;
00137     long long endoffs;
00138 };
00139 
00140 typedef XrdClientVector<XrdClientCacheInterval> XrdClientIntvList;
00141 
00142 class XrdClientReadCache {
00143 private:
00144 
00145     long long       fBytesHit;         // Total number of bytes read with a cache hit
00146     long long       fBytesSubmitted;   // Total number of bytes inserted
00147     float           fBytesUsefulness;
00148     ItemVect        fItems;
00149     long long       fMaxCacheSize;
00150     long long       fMissCount;        // Counter of the cache misses
00151     float           fMissRate;            // Miss rate
00152     XrdSysRecMutex  fMutex;
00153     long long       fReadsCounter;     // Counter of all the attempted reads (hit or miss)
00154     int             fBlkRemPolicy;     // The algorithm used to remove "old" chunks
00155     long long       fTimestampTickCounter;        // Aging mechanism yuk!
00156     long long       fTotalByteCount;
00157 
00158     long long       GetTimestampTick();
00159     bool            MakeFreeSpace(long long bytes);
00160 
00161     bool            RemoveItem();
00162     bool            RemoveLRUItem();
00163     bool            RemoveFirstItem();
00164 
00165     inline void     UpdatePerfCounters() {
00166         if (fReadsCounter > 0)
00167             fMissRate = (float)fMissCount / fReadsCounter;
00168         if (fBytesSubmitted > 0)
00169             fBytesUsefulness = (float)fBytesHit / fBytesSubmitted;
00170     }
00171 
00172     int             FindInsertionApprox(long long begin_offs);
00173     int             FindInsertionApprox_rec(int startidx, int endidx,
00174                                         long long begin_offs);
00175 public:
00176 
00177     // The algos available for the removal of "old" blocks
00178     enum {
00179       kRmBlk_LRU = 0,
00180       kRmBlk_LeastOffs,
00181       kRmBlk_FIFO
00182     };
00183 
00184     XrdClientReadCache();
00185     ~XrdClientReadCache();
00186   
00187     long          GetDataIfPresent(const void *buffer, long long begin_offs,
00188                                    long long end_offs, bool PerfCalc,
00189                                    XrdClientIntvList &missingblks, long &outstandingblks);
00190 
00191   void                       GetInfo(
00192                                           // The actual cache size
00193                                           int &size,
00194 
00195                                           // The number of bytes submitted since the beginning
00196                                           long long &bytessubmitted,
00197 
00198                                           // The number of bytes found in the cache (estimate)
00199                                           long long &byteshit,
00200 
00201                                           // The number of reads which did not find their data
00202                                           // (estimate)
00203                                           long long &misscount,
00204 
00205                                           // miss/totalreads ratio (estimate)
00206                                           float &missrate,
00207 
00208                                           // number of read requests towards the cache
00209                                           long long &readreqcnt,
00210 
00211                                           // ratio between bytes found / bytes submitted
00212                                           float &bytesusefulness
00213                                      );
00214 
00215     inline long long GetTotalByteCount() {
00216         XrdSysMutexHelper m(fMutex);
00217         return fTotalByteCount;
00218     }
00219 
00220     void PutPlaceholder(long long begin_offs, long long end_offs);
00221 
00222     inline void     PrintPerfCounters() {
00223         XrdSysMutexHelper m(fMutex);
00224 
00225         cout << "Low level caching info:" << endl;
00226         cout << " StallsRate=" << fMissRate << endl;
00227         cout << " StallsCount=" << fMissCount << endl;
00228         cout << " ReadsCounter=" << fReadsCounter << endl;
00229         cout << " BytesUsefulness=" << fBytesUsefulness << endl;
00230         cout << " BytesSubmitted=" << fBytesSubmitted << " BytesHit=" << 
00231            fBytesHit << endl << endl;
00232     }
00233 
00234 
00235     void            PrintCache();
00236 
00237     void            SubmitXMessage(XrdClientMessage *xmsg, long long begin_offs,
00238                                    long long end_offs);
00239 
00240     bool            SubmitRawData(const void *buffer, long long begin_offs,
00241                                   long long end_offs, bool pinned=false);
00242 
00243     void            RemoveItems(bool leavepinned=true);
00244     void            RemoveItems(long long begin_offs, long long end_offs, bool remove_overlapped = false);
00245     void            RemovePlaceholders();
00246 
00247 
00248     void            SetSize(int sz) {
00249       fMaxCacheSize = sz;
00250     }
00251 
00252     void            SetBlkRemovalPolicy(int p) {
00253       fBlkRemPolicy = p;
00254     }
00255 
00256     void UnPinCacheBlk(long long begin_offs, long long end_offs);
00257     void *FindBlk(long long begin_offs, long long end_offs);
00258 
00259     // To check if a block dimension will fit into the cache
00260     inline bool   WillFit(long long bc) {
00261         XrdSysMutexHelper m(fMutex);
00262         return (bc < fMaxCacheSize);
00263     }
00264 
00265 };
00266 
00267 #endif

Generated on Tue Jul 5 14:46:18 2011 for ROOT_528-00b_version by  doxygen 1.5.1