|
xrootd
|
00001 #ifndef __XRDOUCCACHESLOT_HH__ 00002 #define __XRDOUCCACHESLOT_HH__ 00003 /******************************************************************************/ 00004 /* */ 00005 /* X r d O u c C a c h e S l o t . h h */ 00006 /* */ 00007 /* (c) 2011 by the Board of Trustees of the Leland Stanford, Jr., University */ 00008 /* All Rights Reserved */ 00009 /* Produced by Andrew Hanushevsky for Stanford University under contract */ 00010 /* DE-AC02-76-SFO0515 with the Department of Energy */ 00011 /******************************************************************************/ 00012 00013 /* This class is used to support a memory cache used by an XrdOucCache actual 00014 implementation. 00015 */ 00016 00017 class XrdOucCacheData; 00018 class XrdOucCacheIO; 00019 class XrdSysSemaphore; 00020 00021 class XrdOucCacheSlot 00022 { 00023 public: 00024 00025 inline void File(XrdOucCacheIO *kV, int you) 00026 {Status.Data = 0; Key = kV; HLink = you; Count = 1;} 00027 00028 static inline int Find(XrdOucCacheSlot *Base, long long What, int n) 00029 {while(n && Base[n].Contents != What) n=Base[n].HLink; 00030 return n; 00031 } 00032 00033 inline void Hide(XrdOucCacheSlot *Base, int *hTab, int hI) 00034 {int j, Slot = this-Base; 00035 if (hTab[hI] == Slot) hTab[hI] = HLink; 00036 else if ((j = hTab[hI])) 00037 {while((hI=Base[j].HLink) && hI != Slot) j=hI; 00038 if (hI) Base[j].HLink = Base[hI].HLink; 00039 } 00040 Count = 0; Contents = -1; 00041 } 00042 00043 static void Init(XrdOucCacheSlot *Base, int Num) 00044 {int i; 00045 Base->Status.LRU.Next = Base->Status.LRU.Prev = 0; 00046 Base->Own.Next = Base->Own.Prev = 0; 00047 for (i = 1; i < Num; i++) 00048 {Base[i].Status.LRU.Next = Base[i].Status.LRU.Prev = i; 00049 Base[i].Own.Next = Base[i].Own.Prev = i; 00050 Base->Push(Base, &Base[i]); 00051 } 00052 } 00053 00054 inline int Pull(XrdOucCacheSlot *Base) 00055 {Base[Status.LRU.Prev].Status.LRU.Next = Status.LRU.Next; 00056 Base[Status.LRU.Next].Status.LRU.Prev = Status.LRU.Prev; 00057 Status.LRU.Next = Status.LRU.Prev = this-Base; 00058 return Status.LRU.Next; 00059 } 00060 00061 inline int Push(XrdOucCacheSlot *Base, XrdOucCacheSlot *sP) 00062 {int UrNum = sP-Base, MyNum = this-Base; 00063 sP->Status.LRU.Next = MyNum; 00064 sP->Status.LRU.Prev = Status.LRU.Prev; 00065 Base[Status.LRU.Prev].Status.LRU.Next = UrNum; 00066 Status.LRU.Prev = UrNum; 00067 return UrNum; 00068 } 00069 00070 inline void Owner(XrdOucCacheSlot *Base) 00071 {Base[Own.Prev].Own.Next = Own.Next; 00072 Base[Own.Next].Own.Prev = Own.Prev; 00073 Own.Next = Own.Prev = this-Base; 00074 } 00075 00076 inline void Owner(XrdOucCacheSlot *Base, XrdOucCacheSlot *sP) 00077 {int UrNum = sP-Base, MyNum = this-Base; 00078 sP->Own.Next = MyNum; sP->Own.Prev = Own.Prev; 00079 Base[Own.Prev].Own.Next = UrNum; Own.Prev = UrNum; 00080 } 00081 00082 inline void reRef(XrdOucCacheSlot *Base) 00083 { Status.LRU.Prev = Base->Status.LRU.Prev; 00084 Base[ Status.LRU.Prev].Status.LRU.Next = this-Base; 00085 Base->Status.LRU.Prev = this-Base; 00086 Status.LRU.Next = 0; 00087 } 00088 00089 inline void unRef(XrdOucCacheSlot *Base) 00090 { Status.LRU.Next = Base->Status.LRU.Next; 00091 Base [Status.LRU.Next].Status.LRU.Prev = this-Base; 00092 Base->Status.LRU.Next = this-Base; 00093 Status.LRU.Prev = 0; 00094 } 00095 00096 struct SlotList 00097 { 00098 int Next; 00099 int Prev; 00100 }; 00101 00102 struct ioQ 00103 {ioQ *Next; 00104 XrdSysSemaphore *ioEnd; 00105 ioQ(ioQ *First, XrdSysSemaphore *ioW) 00106 : Next(First), ioEnd(ioW) {} 00107 }; 00108 00109 union SlotState 00110 {struct ioQ *waitQ; 00111 XrdOucCacheData *Data; 00112 struct SlotList LRU; 00113 int inUse; 00114 }; 00115 00116 union {long long Contents; 00117 XrdOucCacheIO *Key; 00118 }; 00119 SlotState Status; 00120 SlotList Own; 00121 int HLink; 00122 int Count; 00123 00124 static const int lenMask = 0x01ffffff; // Mask to get true value in Count 00125 static const int isShort = 0x80000000; // Short page, Count & lenMask == size 00126 static const int inTrans = 0x40000000; // Segment is in transit 00127 static const int isSUSE = 0x20000000; // Segment is single use 00128 static const int isNew = 0x10000000; // Segment is new (not yet referenced) 00129 00130 XrdOucCacheSlot() : Contents(-1), HLink(0), Count(0) {} 00131 00132 ~XrdOucCacheSlot() {} 00133 }; 00134 #endif
1.7.5