00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00025
00026
00027
00028
00029
00030
00031
00032 class XrdClientReadCacheItem {
00033 private:
00034
00035 bool fIsPlaceholder;
00036
00037 long long fBeginOffset;
00038 void *fData;
00039 long long fEndOffset;
00040 long fTimestampTicks;
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
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
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
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
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
00089
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
00098 if ( (begin_offs >= fBeginOffset) &&
00099 (begin_offs <= fEndOffset) )
00100 b = begin_offs;
00101
00102 if (b < 0) return 0;
00103
00104
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
00128
00129
00130
00131
00132 typedef XrdClientVector<XrdClientReadCacheItem *> ItemVect;
00133
00134
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;
00146 long long fBytesSubmitted;
00147 float fBytesUsefulness;
00148 ItemVect fItems;
00149 long long fMaxCacheSize;
00150 long long fMissCount;
00151 float fMissRate;
00152 XrdSysRecMutex fMutex;
00153 long long fReadsCounter;
00154 int fBlkRemPolicy;
00155 long long fTimestampTickCounter;
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
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
00193 int &size,
00194
00195
00196 long long &bytessubmitted,
00197
00198
00199 long long &byteshit,
00200
00201
00202
00203 long long &misscount,
00204
00205
00206 float &missrate,
00207
00208
00209 long long &readreqcnt,
00210
00211
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
00260 inline bool WillFit(long long bc) {
00261 XrdSysMutexHelper m(fMutex);
00262 return (bc < fMaxCacheSize);
00263 }
00264
00265 };
00266
00267 #endif