00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "XrdFfs/XrdFfsDent.hh"
00011
00012 #ifdef __cplusplus
00013 extern "C" {
00014 #endif
00015
00016
00017
00018
00019 int XrdFfsDent_cstr_cmp(const void *a, const void *b)
00020 {
00021 const char **aa = (const char **)a;
00022 const char **bb = (const char **)b;
00023 return strcmp(*aa, *bb);
00024 }
00025
00026
00027
00028
00029 void XrdFfsDent_names_del(struct XrdFfsDentnames **p)
00030 {
00031 (*p)->name = NULL;
00032 (*p)->next = NULL;
00033 free(*p);
00034 }
00035
00036 void XrdFfsDent_names_add(struct XrdFfsDentnames **p, char *name)
00037 {
00038 struct XrdFfsDentnames *n = (struct XrdFfsDentnames*)malloc(sizeof(struct XrdFfsDentnames));
00039 n->name = strdup(name);
00040
00041 n->next = *p;
00042 *p = n;
00043 return;
00044 }
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 void XrdFfsDent_names_join(struct XrdFfsDentnames **p, struct XrdFfsDentnames **n)
00059 {
00060 struct XrdFfsDentnames *t, *l;
00061
00062 if ( *p != NULL )
00063 {
00064 t = *p;
00065 while ( t != NULL )
00066 {
00067 l = t;
00068 t = t->next;
00069 }
00070 l->next = *n;
00071 }
00072 else
00073 *p = *n;
00074 }
00075
00076
00077
00078
00079
00080 int XrdFfsDent_names_extract(struct XrdFfsDentnames **p, char ***dnarray)
00081 {
00082 struct XrdFfsDentnames *x, *y;
00083 int i = 0;
00084
00085 y = *p;
00086 while (y != NULL)
00087 {
00088 i++;
00089 y = y->next;
00090 }
00091
00092 *dnarray = (char**) malloc(sizeof(char*) * i);
00093
00094 x = *p;
00095 y = *p;
00096 i = 0;
00097 while (y != NULL)
00098 {
00099 (*dnarray)[i++] = y->name;
00100 y = y->next;
00101 XrdFfsDent_names_del(&x);
00102 x = y;
00103 }
00104
00105 qsort((*dnarray), i, sizeof(char*), XrdFfsDent_cstr_cmp);
00106 *p = NULL;
00107 return i;
00108 }
00109
00110
00111
00112 struct XrdFfsDentcache {
00113 time_t t0;
00114 time_t life;
00115 unsigned int nents;
00116 char *dirname;
00117 char **dnarray;
00118 };
00119
00120 void XrdFfsDent_dentcache_fill(struct XrdFfsDentcache *cache, char *dname, char ***dnarray, int nents)
00121 {
00122 int i;
00123
00124 cache->dirname = strdup(dname);
00125 cache->nents = nents;
00126 cache->t0 = time(NULL);
00127 cache->life = nents / 20 ;
00128 cache->dnarray = (char**) malloc(sizeof(char*) * nents);
00129
00130 for (i = 0; i < nents; i++)
00131 cache->dnarray[i] = strdup((*dnarray)[i]);
00132 }
00133
00134 void XrdFfsDent_dentcache_free(struct XrdFfsDentcache *cache)
00135 {
00136 int i;
00137 for (i = 0; i < (int)cache->nents; i++)
00138 {
00139 free(cache->dnarray[i]);
00140 }
00141 cache->nents = 0;
00142 free(cache->dnarray);
00143 free(cache->dirname);
00144 cache->dnarray = NULL;
00145 cache->dirname = NULL;
00146 }
00147
00148
00149 int XrdFfsDent_dentcache_expired(struct XrdFfsDentcache *cache)
00150 {
00151 time_t t1;
00152 t1 = time(NULL);
00153 return (((t1 - cache->t0) < cache->life)? 0 : 1);
00154 }
00155
00156 int XrdFfsDent_dentcache_invalid(struct XrdFfsDentcache *cache)
00157 {
00158 time_t t1;
00159 t1 = time(NULL);
00160 return (((t1 - cache->t0) < 28700)? 0 : 1);
00161 }
00162
00163 int XrdFfsDent_dentcache_search(struct XrdFfsDentcache *cache, char *dname, char *dentname)
00164 {
00165 char path[1024];
00166
00167 strcpy(path, dname);
00168 if (dentname != NULL && path[strlen(path) -1] != '/')
00169 strcat(path,"/");
00170 if (dentname != NULL) strcat(path, dentname);
00171 if (XrdFfsDent_dentcache_invalid(cache))
00172 return 0;
00173 else if (strlen(cache->dirname) == strlen(path) && strcmp(cache->dirname, path) == 0)
00174 return 1;
00175 else if (strlen(cache->dirname) != strlen(dname) || strcmp(cache->dirname, dname) != 0)
00176 return 0;
00177 else if (bsearch(&dentname, cache->dnarray, cache->nents, sizeof(char*), XrdFfsDent_cstr_cmp) != NULL)
00178 return 1;
00179 else
00180 return 0;
00181 }
00182
00183 #define XrdFfsDent_NDENTCACHES 20
00184 struct XrdFfsDentcache XrdFfsDentCaches[XrdFfsDent_NDENTCACHES];
00185 pthread_mutex_t XrdFfsDentCaches_mutex = PTHREAD_MUTEX_INITIALIZER;
00186
00187 void XrdFfsDent_cache_init()
00188 {
00189 int i;
00190 for (i = 0; i < XrdFfsDent_NDENTCACHES; i++)
00191 {
00192 XrdFfsDentCaches[i].t0 = 0;
00193 XrdFfsDentCaches[i].nents = 0;
00194 XrdFfsDentCaches[i].dirname = strdup("");
00195 XrdFfsDentCaches[i].dnarray = NULL;
00196 }
00197 }
00198
00199 int XrdFfsDent_cache_fill(char *dname, char ***dnarray, int nents)
00200 {
00201 int i;
00202 pthread_mutex_lock(&XrdFfsDentCaches_mutex);
00203 for (i = 0; i < XrdFfsDent_NDENTCACHES; i++)
00204 {
00205 if (XrdFfsDent_dentcache_search(&XrdFfsDentCaches[i], dname, NULL) != 0)
00206 {
00207 XrdFfsDent_dentcache_free(&XrdFfsDentCaches[i]);
00208 XrdFfsDent_dentcache_fill(&XrdFfsDentCaches[i], dname, dnarray, nents);
00209 pthread_mutex_unlock(&XrdFfsDentCaches_mutex);
00210 return 1;
00211 }
00212 }
00213 for (i = 0; i < XrdFfsDent_NDENTCACHES; i++)
00214 {
00215 if (XrdFfsDent_dentcache_expired(&XrdFfsDentCaches[i]) || XrdFfsDent_dentcache_invalid(&XrdFfsDentCaches[i]))
00216 {
00217 XrdFfsDent_dentcache_free(&XrdFfsDentCaches[i]);
00218 XrdFfsDent_dentcache_fill(&XrdFfsDentCaches[i], dname, dnarray, nents);
00219 pthread_mutex_unlock(&XrdFfsDentCaches_mutex);
00220 return 1;
00221 }
00222 }
00223 pthread_mutex_unlock(&XrdFfsDentCaches_mutex);
00224 return 0;
00225 }
00226
00227 int XrdFfsDent_cache_search(char *dname, char *dentname)
00228 {
00229 int i, rval = 0;
00230 pthread_mutex_lock(&XrdFfsDentCaches_mutex);
00231 for (i = 0; i < XrdFfsDent_NDENTCACHES; i++)
00232 if (XrdFfsDent_dentcache_search(&XrdFfsDentCaches[i], dname, dentname) == 1)
00233 {
00234 rval = 1;
00235 break;
00236 }
00237 pthread_mutex_unlock(&XrdFfsDentCaches_mutex);
00238 return rval;
00239 }
00240
00241 void XrdFfsDent_cache_destroy()
00242 {
00243 int i;
00244 for (i = 0; i < XrdFfsDent_NDENTCACHES; i++)
00245 XrdFfsDent_dentcache_free(&XrdFfsDentCaches[i]);
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 #ifdef __cplusplus
00323 }
00324 #endif