/******************************************************************************/ /* */ /* X r d C m s P L i s t . c c */ /* */ /* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University */ /* All Rights Reserved */ /* Produced by Andrew Hanushevsky for Stanford University under contract */ /* DE-AC02-76-SFO0515 with the Department of Energy */ /* */ /* This file is part of the XRootD software suite. */ /* */ /* XRootD is free software: you can redistribute it and/or modify it under */ /* the terms of the GNU Lesser General Public License as published by the */ /* Free Software Foundation, either version 3 of the License, or (at your */ /* option) any later version. */ /* */ /* XRootD is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */ /* License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */ /* COPYING (GPL license). If not, see . */ /* */ /* The copyright holder's institutional names and contributor's names may not */ /* be used to endorse or promote products derived from this software without */ /* specific prior written permission of the institution or contributor. */ /******************************************************************************/ #include "XrdCms/XrdCmsPList.hh" /******************************************************************************/ /* A d d */ /******************************************************************************/ /******************************************************************************/ /* I n s e r t */ /******************************************************************************/ int XrdCmsPList_Anchor::Add(const char *pname, XrdCmsPInfo *pinfo) { int plen = strlen(pname); XrdCmsPList *p, *pp; // Set up the search // Lock(); p = next; pp = 0; // Find the proper insertion point. Paths are sorted in decreasin length order. // while(p && p->pathlen >= plen) {if (p->pathlen == plen && !strcmp(p->pathname,pname)) {UnLock(); return 0;} pp = p; p = p->next; } // Insert a new element // p = new XrdCmsPList(pname, pinfo); if (pp) { p->next = pp->next; pp->next = p;} else { p->next = next; next = p;} // All done // UnLock(); return 1; } /******************************************************************************/ /* F i n d */ /******************************************************************************/ int XrdCmsPList_Anchor::Find(const char *pname, XrdCmsPInfo &pinfo) { int plen = strlen(pname); // Lock the anchor and setup for search // Lock(); XrdCmsPList *p = next; // Find matching entry // while(p) if (p->pathlen <= plen && !strncmp(p->pathname, pname, p->pathlen)) {pinfo = p->pathmask; break;} else p = p->next; // All done // UnLock(); return p != 0; } /******************************************************************************/ /* I n s e r t */ /******************************************************************************/ SMask_t XrdCmsPList_Anchor::Insert(const char *pname, XrdCmsPInfo *pinfo) { int rc, plen = strlen(pname); XrdCmsPList *p, *pp; SMask_t newmask; // Set up the search // Lock(); p = next; pp = 0; // Find the proper insertion point. Paths are sorted in decreasin length // order. We must merge in the incomming mask with all subset paths. // rc = 1; while(p && p->pathlen >= plen) {if (p->pathlen == plen && !(rc = strcmp(p->pathname,pname))) break; else if (!strncmp(p->pathname,pname,plen) && !(p->pathmask.rovec & pinfo->rovec)) {p->pathmask.And(~(pinfo->rovec)); p->pathmask.Or(pinfo);} pp = p; p = p->next; } // Either merge the path masks or insert a new path. For a new path, add to // it masks of all superset paths that may follow it in the chain of paths. // if (!rc) {p->pathmask.And(~(pinfo->rovec)); p->pathmask.Or(pinfo);} else { p = new XrdCmsPList(pname, pinfo); if (pp) { p->next = pp->next; pp->next = p; } else { p->next = next; next = p; } pp = p->next; while(pp) {if (pp->pathlen < plen && !strncmp(pp->pathname,pname,pp->pathlen)) p->pathmask.Or(&(pp->pathmask)); pp = pp->next; } } // All done // newmask = p->pathmask.rovec | p->pathmask.rwvec; UnLock(); return newmask; } /******************************************************************************/ /* R e m o v e */ /******************************************************************************/ void XrdCmsPList_Anchor::Remove(SMask_t mask) { SMask_t zmask(~mask); XrdCmsPList *pp = next, *prevp = 0; // Lock the list // Lock(); // Remove bit from mask. If mask is zero, remove the entry // while(pp) {if (!pp->pathmask.And(zmask)) {if (prevp) {prevp->next = pp->next; delete pp; pp = prevp->next;} else { next = pp->next; delete pp; pp = next;} } else {prevp = pp; pp = pp->next;} } // All done // UnLock(); } /******************************************************************************/ /* F i n d */ /******************************************************************************/ const char *XrdCmsPList_Anchor::Type(const char *pname) { int isrw = 0, plen = strlen(pname); // Lock the anchor and setup for search // Lock(); XrdCmsPList *p = next; // Find matching entry // while(p) if (p->pathlen <= plen && !strncmp(p->pathname, pname, p->pathlen)) {isrw = (p->pathmask.rwvec != 0); break;} else p = p->next; // All done // UnLock(); if (p) return (isrw ? "w" : "r"); return "?"; } /******************************************************************************/ /* P T y p e */ /******************************************************************************/ const char *XrdCmsPList::PType() { if (pathmask.ssvec) return (pathmask.rwvec ? "ws" : "rs"); return (pathmask.rwvec ? "w" : "r"); }