31 #include <sys/types.h>
57 while (cachemx > -1) {
58 if (cachent[cachemx]) {
59 delete cachent[cachemx];
90 capacity = (capacity > 0) ? capacity : 100;
95 for (
int i = 0; i < capacity; i++) { cachent[i] = 0; }
97 DEBUG(
"cache allocated for "<<cachesz<<
" entries");
104 DEBUG(
"problems initialising hash table");
107 if (lock) rwlock.
UnLock();
111 DEBUG(
"could not allocate cache - out-of-resources ");
117 if (lock) rwlock.
UnLock();
136 if (!
ID || !strlen(
ID)) {
143 DEBUG(
"problems rehashing");
152 for (i = 0; i < maxTries; i++)
153 {
if ((pfEnt = Get(
ID, wild)))
162 {
DEBUG(
"problems rehashing");
165 isg.
Lock(&rwlock, 1);
178 if (ie && *ie >= 0 && *ie < cachesz) {
186 int i = 0, match = 0, nmmax = 0, iref = -1;
187 for (; i <= cachemx; i++) {
189 match = sid.matches(cachent[i]->name);
198 return cachent[iref];
216 if (!
ID || !strlen(
ID)) {
232 if (cachemx == cachesz - 1) {
237 DEBUG(
"could not extend cache to size: "<<(2*cachesz));
245 for (; i <= cachemx; i++) {
247 newcache[nmx] = cachent[i];
255 for (i = cachemx + 1; i <= cachemx; i++) {
268 int pos = cachemx + 1;
276 DEBUG(
"could not allocate space for new cache entry");
283 if (
Rehash(force, 0) != 0) {
284 DEBUG(
"problems re-hashing");
289 urRef.
Lock(&(cachent[pos]->pfeMutex));
303 if (!
ID || !strlen(
ID)) {
312 DEBUG(
"problems rehashing");
321 if (*ie >= 0 && *ie < cachesz) {
328 if (cachent[pos] && !strcmp(cachent[pos]->name,
ID)) {
329 if (!Delete(cachent[pos]))
DEBUG(
"Delete deferred for " <<
ID);
340 for (; i >= 0; i--) {
342 if (!strncmp(cachent[i]->name,
ID,strlen(
ID))) {
343 if (!Delete(cachent[i]))
DEBUG(
"Delete deferred for " <<
ID);
357 DEBUG(
"problems re-hashing");
369 struct pfQ {pfQ *next;
372 : next(cP), pfEnt(tP) {}
373 ~pfQ() {
delete pfEnt;}
376 static pfQ pfDefer(0,0);
381 {pfQ *pQ = &pfDefer, *dQ;
382 int nTot = 0, dTot = 0;
383 while((dQ = pQ->next))
385 if (dQ->pfEnt->pfeMutex.CondLock())
386 {pQ->next = dQ->next;
387 dQ->pfEnt->pfeMutex.UnLock();
392 if (nTot)
DEBUG(
"Deferred delete " <<dTot <<
" of " <<nTot);
405 pfDefer.next =
new pfQ(pfDefer.next, pfEnt);
422 lifet = (lifet > 0) ? lifet : lifetime;
426 int reftime = time(0) - lifet;
429 int i = cachemx, nrm = 0;
430 for (; i >= 0; i--) {
431 if (cachent[i] && cachent[i]->mtime < reftime) {
432 if (!Delete(cachent[i]))
433 DEBUG(
"Delete deferred for " <<cachent[i]->name);
460 for (; i >= 0; i--) {
462 if (!Delete(cachent[i]))
463 DEBUG(
"Delete deferred for " <<cachent[i]->name);
470 if (newsz > -1 && newsz != cachesz) {
480 if (lock) rwlock.
UnLock();
492 PRINT(
"//-----------------------------------------------------");
494 if (msg && strlen(msg) > 0) {
498 PRINT(
"// Capacity: "<<cachesz);
499 PRINT(
"// Max index filled: "<<cachemx);
509 for (; i <= cachemx; i++) {
512 if ((ent = cachent[i])) {
521 <<
" name:"<<ent->
name);
527 PRINT(
"//-----------------------------------------------------");
539 DEBUG(
"invalid input file name");
545 if (
stat(pfn,&st) == -1) {
546 DEBUG(
"cannot stat file (errno: "<<errno<<
")");
549 if (utime > -1 && utime > st.st_mtime) {
550 DEBUG(
"cached information for file "<<pfn<<
" is up-to-date");
566 if (ff.ReadHeader(header) < 0) {
573 DEBUG(
"PFEntry file is empty - default init and return");
582 DEBUG(
"problems allocating / resizing cache ");
591 while (nxtofs > 0 && ne < header.
entries) {
594 if (ff.ReadInd(nxtofs, ind) < 0) {
595 DEBUG(
"problems reading index entry ");
605 if (ff.ReadEnt(ind.
entofs, ent) < 0) {
624 DEBUG(
"problems duplicating entry for cache");
635 DEBUG(
"WARNING: inconsistent number of entries: possible file corruption");
646 DEBUG(
"PF file "<<pfn<<
" loaded in cache (found "<<ne<<
" entries)");
650 DEBUG(
"problems creating hash table");
669 if (htmtime >= utime && !force) {
671 if (lock) rwlock.
UnLock();
679 for (; i <= cachemx; i++) {
684 TRACE(
Dump,
"Adding ID: "<<cachent[i]->name<<
"; key: "<<*key);
685 hashtable.
Add(cachent[i]->name,key);
694 if (lock) rwlock.
UnLock();
696 DEBUG(
"Hash table updated (found "<<nht<<
" active entries)");
711 if (!pfn && pfile.
length() <= 0) {
712 DEBUG(
"invalid input");
721 DEBUG(
"cannot attach-to or create file "<<pfn<<
" ("<<ff.
LastErrStr()<<
")");
730 int i = 0, nr = 0, nfs = 0;
731 for (; i <= cachemx; i++ ) {
743 if (nr == 0 || cachent[i]->mtime > ent.
mtime) {
763 DEBUG(
"Cache flushed to file "<<pfn<<
" ("<<nfs<<
" entries updated / written)");
776 if (pfile.
length() <= 0) {
777 DEBUG(
"cache was not initialized from file - do nothing");
784 DEBUG(
"cannot stat file (errno: "<<errno<<
")");
787 if (utime > -1 && utime > st.st_mtime) {
788 DEBUG(
"cached information for file "<<pfile<<
" is up-to-date");
796 DEBUG(
"problems loading passwd information from file: "<<pfile);
803 DEBUG(
"Cache refreshed from file: "<<pfile);
int stat(const char *path, struct stat *buf)
int XrdSutTimeString(int t, char *st, int opt)
T * Add(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
T * Find(const char *KeyVal, time_t *KeyTime=0)
const char * c_str() const
void Lock(XrdSysMutex *Mutex)
void Set(XrdSysMutex *Mutex)
bool Remove(const char *ID, int opt=1)
int Flush(const char *pfname=0)
XrdSutPFEntry * Add(XrdSutPFCacheRef &urRef, const char *ID, bool force=0)
int Reset(int newsz=-1, bool lock=1)
int Init(int capacity=100, bool lock=1)
void Dump(const char *msg=0)
int Load(const char *pfname)
int Rehash(bool force=0, bool lock=1)
void SetName(const char *n=0)
kXR_int32 WriteEntry(XrdSutPFEntry ent)
const char * LastErrStr() const
kXR_int32 Close(kXR_int32 d=-1)
kXR_int32 ReadEntry(const char *name, XrdSutPFEntry &ent, int opt=0)
void Lock(XrdSysRWLock *lock, bool rd=1)
static void Wait(int milliseconds)