00001 #ifndef XRD_READCACHE_H
00002 #define XRD_READCACHE_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032
00033
00035
00036 #include "XrdSys/XrdSysHeaders.hh"
00037 #include "XrdClient/XrdClientInputBuffer.hh"
00038 #include "XrdClient/XrdClientMessage.hh"
00039 #include "XrdClient/XrdClientVector.hh"
00040 #include "XrdClient/XrdClientConst.hh"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 class XrdClientReadCacheItem {
00052 private:
00053
00054 bool fIsPlaceholder;
00055
00056 long long fBeginOffset;
00057 void *fData;
00058 long long fEndOffset;
00059 long fTimestampTicks;
00060
00061 public:
00062 XrdClientReadCacheItem(const void *buffer, long long begin_offs,
00063 long long end_offs, long long ticksnow,
00064 bool placeholder=false);
00065 ~XrdClientReadCacheItem();
00066
00067 inline long long BeginOffset() { return fBeginOffset; }
00068 inline long long EndOffset() { return fEndOffset; }
00069
00070
00071 inline bool ContainedInInterval(long long begin_offs, long long end_offs) {
00072 return ( (end_offs >= begin_offs) &&
00073 (fBeginOffset >= begin_offs) &&
00074 (fEndOffset <= end_offs) );
00075 }
00076
00077
00078 inline bool ContainsInterval(long long begin_offs, long long end_offs) {
00079 return ( (end_offs > begin_offs) &&
00080 (fBeginOffset <= begin_offs) && (fEndOffset >= end_offs) );
00081 }
00082
00083
00084 inline bool IntersectInterval(long long begin_offs, long long end_offs) {
00085 if ( ContainsOffset( begin_offs ) || ContainsOffset( end_offs ) ) return true;
00086 if ( (fBeginOffset >= begin_offs) && (fBeginOffset <= end_offs) ) return true;
00087 return false;
00088 }
00089
00090
00091 inline bool ContainsOffset(long long offs) {
00092 return (fBeginOffset <= offs) && (fEndOffset >= offs);
00093 }
00094
00095 void *GetData() { return fData; }
00096
00097
00098 inline bool GetInterval(const void *buffer, long long begin_offs,
00099 long long end_offs) {
00100 if (!ContainsInterval(begin_offs, end_offs))
00101 return FALSE;
00102 memcpy((void *)buffer, ((char *)fData)+(begin_offs - fBeginOffset),
00103 end_offs - begin_offs + 1);
00104 return TRUE;
00105 }
00106
00107
00108
00109 inline long GetPartialInterval(const void *buffer, long long begin_offs,
00110 long long end_offs) {
00111
00112 long long b = -1, e, l;
00113
00114 if (begin_offs > end_offs) return 0;
00115
00116
00117 if ( (begin_offs >= fBeginOffset) &&
00118 (begin_offs <= fEndOffset) )
00119 b = begin_offs;
00120
00121 if (b < 0) return 0;
00122
00123
00124 e = xrdmin(end_offs, fEndOffset);
00125
00126 l = e - b + 1;
00127
00128 if (buffer && fData)
00129 memcpy((void *)buffer, ((char *)fData)+(b - fBeginOffset), l);
00130
00131 return l;
00132 }
00133
00134 inline long long GetTimestampTicks() { return(fTimestampTicks); }
00135
00136 inline bool IsPlaceholder() { return fIsPlaceholder; }
00137
00138 long Size() { return (fEndOffset - fBeginOffset + 1); }
00139
00140 inline void Touch(long long ticksnow) { fTimestampTicks = ticksnow; }
00141
00142 bool Pinned;
00143 };
00144
00145
00146
00147
00148
00149
00150
00151 typedef XrdClientVector<XrdClientReadCacheItem *> ItemVect;
00152
00153
00154 struct XrdClientCacheInterval {
00155 long long beginoffs;
00156 long long endoffs;
00157 };
00158
00159 typedef XrdClientVector<XrdClientCacheInterval> XrdClientIntvList;
00160
00161 class XrdClientReadCache {
00162 private:
00163
00164 long long fBytesHit;
00165 long long fBytesSubmitted;
00166 float fBytesUsefulness;
00167 ItemVect fItems;
00168 long long fMaxCacheSize;
00169 long long fMissCount;
00170 float fMissRate;
00171 XrdSysRecMutex fMutex;
00172 long long fReadsCounter;
00173 int fBlkRemPolicy;
00174 long long fTimestampTickCounter;
00175 long long fTotalByteCount;
00176
00177 long long GetTimestampTick();
00178 bool MakeFreeSpace(long long bytes);
00179
00180 bool RemoveItem();
00181 bool RemoveLRUItem();
00182 bool RemoveFirstItem();
00183
00184 inline void UpdatePerfCounters() {
00185 if (fReadsCounter > 0)
00186 fMissRate = (float)fMissCount / fReadsCounter;
00187 if (fBytesSubmitted > 0)
00188 fBytesUsefulness = (float)fBytesHit / fBytesSubmitted;
00189 }
00190
00191 int FindInsertionApprox(long long begin_offs);
00192 int FindInsertionApprox_rec(int startidx, int endidx,
00193 long long begin_offs);
00194 public:
00195
00196
00197 enum {
00198 kRmBlk_LRU = 0,
00199 kRmBlk_LeastOffs,
00200 kRmBlk_FIFO
00201 };
00202
00203 XrdClientReadCache();
00204 ~XrdClientReadCache();
00205
00206 long GetDataIfPresent(const void *buffer, long long begin_offs,
00207 long long end_offs, bool PerfCalc,
00208 XrdClientIntvList &missingblks, long &outstandingblks);
00209
00210 void GetInfo(
00211
00212 int &size,
00213
00214
00215 long long &bytessubmitted,
00216
00217
00218 long long &byteshit,
00219
00220
00221
00222 long long &misscount,
00223
00224
00225 float &missrate,
00226
00227
00228 long long &readreqcnt,
00229
00230
00231 float &bytesusefulness
00232 );
00233
00234 inline long long GetTotalByteCount() {
00235 XrdSysMutexHelper m(fMutex);
00236 return fTotalByteCount;
00237 }
00238
00239 void PutPlaceholder(long long begin_offs, long long end_offs);
00240
00241 inline void PrintPerfCounters() {
00242 XrdSysMutexHelper m(fMutex);
00243
00244 cout << "Low level caching info:" << endl;
00245 cout << " StallsRate=" << fMissRate << endl;
00246 cout << " StallsCount=" << fMissCount << endl;
00247 cout << " ReadsCounter=" << fReadsCounter << endl;
00248 cout << " BytesUsefulness=" << fBytesUsefulness << endl;
00249 cout << " BytesSubmitted=" << fBytesSubmitted << " BytesHit=" <<
00250 fBytesHit << endl << endl;
00251 }
00252
00253
00254 void PrintCache();
00255
00256 void SubmitXMessage(XrdClientMessage *xmsg, long long begin_offs,
00257 long long end_offs);
00258
00259 bool SubmitRawData(const void *buffer, long long begin_offs,
00260 long long end_offs, bool pinned=false);
00261
00262 void RemoveItems(bool leavepinned=true);
00263 void RemoveItems(long long begin_offs, long long end_offs, bool remove_overlapped = false);
00264 void RemovePlaceholders();
00265
00266
00267 void SetSize(int sz) {
00268 fMaxCacheSize = sz;
00269 }
00270
00271 void SetBlkRemovalPolicy(int p) {
00272 fBlkRemPolicy = p;
00273 }
00274
00275 void UnPinCacheBlk(long long begin_offs, long long end_offs);
00276 void *FindBlk(long long begin_offs, long long end_offs);
00277
00278
00279 inline bool WillFit(long long bc) {
00280 XrdSysMutexHelper m(fMutex);
00281 return (bc < fMaxCacheSize);
00282 }
00283
00284 };
00285 #endif