xrootd
XrdOucCacheSlot.hh
Go to the documentation of this file.
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