XrdCmsKey.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                          X r d C m s K e y . c c                           */
00004 /*                                                                            */
00005 /* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //         $Id: XrdCmsKey.cc 30949 2009-11-02 16:37:58Z ganis $
00012 
00013 const char *XrdCmsKeyCVSID = "$Id: XrdCmsKey.cc 30949 2009-11-02 16:37:58Z ganis $";
00014 
00015 #include <errno.h>
00016 #include <string.h>
00017 
00018 #include "XrdCms/XrdCmsKey.hh"
00019 #include "XrdCms/XrdCmsTrace.hh"
00020 #include "XrdOuc/XrdOucCRC.hh"
00021 #include "XrdSys/XrdSysError.hh"
00022 
00023 using namespace XrdCms;
00024 
00025 /******************************************************************************/
00026 /*                       C l a s s   X r d C m s K e y                        */
00027 /******************************************************************************/
00028 /******************************************************************************/
00029 /* public                        s e t H a s h                                */
00030 /******************************************************************************/
00031   
00032 void XrdCmsKey::setHash()
00033 {
00034      if (!Len) Len = strlen(Val);
00035      if (!(Hash = XrdOucCRC::CRC32((const unsigned char *)Val, Len))) Hash = 1;
00036 }
00037 
00038 /******************************************************************************/
00039 /*                   C l a s s   X r d C m s K e y I t e m                    */
00040 /******************************************************************************/
00041 /******************************************************************************/
00042 /*                           S t a t i c   D a t a                            */
00043 /******************************************************************************/
00044   
00045 XrdCmsKeyItem *XrdCmsKeyItem::TockTable[TickRate] = {0};
00046 XrdCmsKeyItem *XrdCmsKeyItem::Free    = 0;
00047 int            XrdCmsKeyItem::numFree = 0;
00048 int            XrdCmsKeyItem::numHave = 0;
00049 int            XrdCmsKeyItem::numNull = 0;
00050 
00051 /******************************************************************************/
00052 /* static public                   A l l o c                                  */
00053 /******************************************************************************/
00054   
00055 XrdCmsKeyItem *XrdCmsKeyItem::Alloc(unsigned int theTock)
00056 {
00057   XrdCmsKeyItem *kP;
00058 
00059 // Try to allocate an existing item or replenish the list
00060 //
00061    do {if ((kP = Free))
00062           {Free = kP->Next;
00063            numFree--;
00064            theTock &= TickMask;
00065            kP->Key.TOD    = theTock;
00066            kP->Key.TODRef = TockTable[theTock];
00067            TockTable[theTock] = kP;
00068            if (!(kP->Key.Ref++)) kP->Key.Ref = 1;
00069             kP->Loc.roPend = kP->Loc.rwPend = 0;
00070            return kP;
00071           }
00072        numNull++;
00073        } while(Replenish());
00074 
00075 // We failed
00076 //
00077    Say.Emsg("Key", ENOMEM, "create key item");
00078    return (XrdCmsKeyItem *)0;
00079 }
00080 
00081 /******************************************************************************/
00082 /* public                        R e c y c l e                                */
00083 /******************************************************************************/
00084   
00085 void XrdCmsKeyItem::Recycle()
00086 {
00087    static char *noKey = (char *)"";
00088 
00089 // Clear up data areas
00090 //
00091    if (Key.Val && Key.Val != noKey) {free(Key.Val); Key.Val = noKey;}
00092    Key.Ref++; Key.Hash = 0;
00093 
00094 // Put entry on the free list
00095 //
00096    Next = Free; Free = this;
00097    numFree++;
00098 }
00099 
00100 /******************************************************************************/
00101 /* public                         R e l o a d                                 */
00102 /******************************************************************************/
00103   
00104 void XrdCmsKeyItem::Reload()
00105 {
00106    Key.TOD &= static_cast<unsigned char>(TickMask);
00107    Key.TODRef = TockTable[Key.TOD];
00108    TockTable[Key.TOD] = this;
00109 }
00110 
00111 /******************************************************************************/
00112 /* static public               R e p l e n i s h                              */
00113 /******************************************************************************/
00114 
00115 int XrdCmsKeyItem::Replenish()
00116 {
00117    EPNAME("Replenish");
00118    XrdCmsKeyItem *kP;
00119    int i;
00120 
00121 // Allocate a quantum of free elements and chain them into the free list
00122 //
00123    if (!(kP = new XrdCmsKeyItem[minAlloc])) return 0;
00124    DEBUG("old free " <<numFree <<" + " <<minAlloc <<" = " <<numHave+minAlloc);
00125 
00126 // We would do this in an initializer but that causes problems when alloacting
00127 // temporary items on the stack. So, manually put these on the free list.
00128 //
00129    i = minAlloc;
00130    while(i--) {kP->Next = Free; Free = kP; kP++;}
00131   
00132 // Return the number we have free
00133 //
00134    numHave += minAlloc;
00135    numFree += minAlloc;
00136    return numFree;
00137 }
00138 
00139 /******************************************************************************/
00140 /* static public                   S t a t s                                  */
00141 /******************************************************************************/
00142 
00143 void XrdCmsKeyItem::Stats(int &isAlloc, int &isFree, int &wasNull)
00144 {
00145 
00146    isAlloc  = numHave;
00147    isFree   = numFree;
00148    wasNull  = numNull;
00149    numNull  = 0;
00150 }
00151 
00152 /******************************************************************************/
00153 /* static public                  U n l o a d                                 */
00154 /******************************************************************************/
00155   
00156 XrdCmsKeyItem *XrdCmsKeyItem::Unload(unsigned int theTock)
00157 {
00158    XrdCmsKeyItem myItem, *nP, *pP = &myItem;
00159 
00160 // Remove all entries from the indicated list. If any entries have been
00161 // reassigned to a different list, move them to the right list. Otherwise,
00162 // make the entry unfindable by clearing the hash code. Since item recycling
00163 // requires knowing the hash code, we save it elsewhere in the object.
00164 //
00165    theTock &= TickMask;
00166    myItem.Key.TODRef = TockTable[theTock]; TockTable[theTock] = 0;
00167    while((nP = pP->Key.TODRef))
00168          if (nP->Key.TOD == theTock) 
00169             {nP->Loc.HashSave = nP->Key.Hash; nP->Key.Hash = 0; pP = nP;}
00170             else {pP->Key.TODRef = nP->Key.TODRef;
00171                   nP->Key.TODRef = TockTable[nP->Key.TOD];
00172                   TockTable[nP->Key.TOD] = nP;
00173                  }
00174    return myItem.Key.TODRef;
00175 }
00176 
00177 /******************************************************************************/
00178   
00179 XrdCmsKeyItem *XrdCmsKeyItem::Unload(XrdCmsKeyItem *theItem)
00180 {
00181    XrdCmsKeyItem *kP, *pP = 0;
00182    unsigned int theTock = theItem->Key.TOD & TickMask;
00183 
00184 // Remove the entry from the right list
00185 //
00186    kP = TockTable[theTock];
00187    while(kP && kP != theItem) {pP = kP; kP = kP->Key.TODRef;}
00188    if (kP)
00189       {if (pP) pP->Key.TODRef     = kP->Key.TODRef;
00190           else TockTable[theTock] = kP->Key.TODRef;
00191        kP->Loc.HashSave = kP->Key.Hash; kP->Key.Hash = 0;
00192       }
00193    return kP;
00194 }

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