LAL  7.5.0.1-b72065a
LALCache.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 #define _GNU_SOURCE /* for realpath() */
21 
22 #include <config.h>
23 #include <stdlib.h>
24 #include <limits.h>
25 #include <stdio.h>
26 #include <string.h>
27 
28 #ifdef HAVE_REGEX_H
29 #include <regex.h>
30 #endif
31 
32 #ifdef HAVE_GLOB_H
33 #include <glob.h>
34 #endif
35 
36 #include <lal/LALStdio.h>
37 #include <lal/LALStdlib.h>
38 #include <lal/LALString.h>
39 #include <lal/Sort.h>
40 #include <lal/LALCache.h>
41 #include <lal/FileIO.h>
42 
43 #ifdef __GNUC__
44 #define UNUSED __attribute__ ((unused))
45 #else
46 #define UNUSED
47 #endif
48 
49 /* for e.g. MinGW */
50 #ifndef NAME_MAX
51 #define NAME_MAX FILENAME_MAX
52 #endif
53 
54 static int XLALCacheFileReadRow(char *s, size_t len, LALFILE * fp,
55  int *line)
56 {
57  while (1) {
58  if (!XLALFileGets(s, len, fp))
59  return 0; /* finished code */
60  ++(*line);
61  if (!strchr(s, '\n')) {
62  if (XLALFileEOF(fp)) { /* missing final newline */
63  XLAL_PRINT_WARNING("Missing newline on line %d", *line);
64  return 0;
65  }
66  /* line is too long */
67  XLAL_ERROR(XLAL_EIO, "Line %d too long", *line);
68  }
69  if (*s != '#')
70  break;
71  }
72  return 1; /* continue code */
73 }
74 
75 /* counts the rows of the file */
76 static int XLALCacheFileCountRows(LALFILE * fp)
77 {
78  char s[PATH_MAX + 4 * (NAME_MAX + 1)];
79  int line = 0;
80  int n = 0;
81  int c;
82  while ((c = XLALCacheFileReadRow(s, sizeof(s), fp, &line)))
83  if (c < 0)
84  return -1;
85  else
86  ++n;
87  return n;
88 }
89 
90 /* kind of like strtok -- modifies buffer */
91 static char *XLALCacheFileNextField(char **ps)
92 {
93  const char *sepstr = " \t\n";
94  char *s = *ps;
95  char *field;
96  size_t len;
97  len = strcspn(s, sepstr);
98  if (!len)
99  return NULL;
100  field = s;
101  s += len;
102  *s++ = 0;
103  s += strspn(s, sepstr);
104  *ps = s;
105  return field;
106 }
107 
108 
109 /* Parses a row into appropriate fields in the cache entry */
110 /* NOTE: perfectly happy if there is too many rows! */
111 static int XLALCacheFileParseEntry(struct tagLALCacheEntry *entry, char *s)
112 {
113  char *f1, *f2, *f3, *f4, *f5;
114  if ((f1 = XLALCacheFileNextField(&s))
115  && (f2 = XLALCacheFileNextField(&s))
116  && (f3 = XLALCacheFileNextField(&s))
117  && (f4 = XLALCacheFileNextField(&s))
118  && (f5 = XLALCacheFileNextField(&s))) {
119  entry->src = strcmp(f1, "-") ? XLALStringDuplicate(f1) : NULL;
120  entry->dsc = strcmp(f2, "-") ? XLALStringDuplicate(f2) : NULL;
121  entry->url = strcmp(f5, "-") ? XLALStringDuplicate(f5) : NULL;
122  if (strcmp(f3, "-")) {
123  if (strspn(f3, "0123456789") != strlen(f3))
124  XLAL_ERROR(XLAL_EIO, "Invalid content in field 3 \"%s\"",
125  f3);
126  entry->t0 = atoi(f3);
127  } else
128  entry->t0 = 0;
129  if (strcmp(f4, "-")) {
130  if (strspn(f4, "0123456789") != strlen(f4))
131  XLAL_ERROR(XLAL_EIO, "Invalid content in field 4 \"%s\"",
132  f4);
133  entry->dt = atoi(f4);
134  } else
135  entry->dt = 0;
136  return 0;
137  }
138  XLAL_ERROR(XLAL_EIO, "Wrong number of fields"); /* wrong field count */
139 }
140 
142  const LALCacheEntry * src)
143 {
144  if (!src || !dst)
146  dst->src = XLALStringDuplicate(src->src);
147  dst->dsc = XLALStringDuplicate(src->dsc);
148  dst->url = XLALStringDuplicate(src->url);
149  dst->t0 = src->t0;
150  dst->dt = src->dt;
151  return 0;
152 }
153 
155 {
156  LALCache *cache;
157  cache = XLALCalloc(1, sizeof(*cache));
158  if (!cache)
160  if (length) {
161  cache->list = XLALCalloc(length, sizeof(*cache->list));
162  if (!cache->list) {
163  XLALFree(cache);
165  }
166  } else
167  XLAL_PRINT_WARNING("Creating a zero-length cache");
168  cache->length = length;
169  return cache;
170 }
171 
173 {
174  if (cache) {
175  UINT4 i;
176  for (i = 0; i < cache->length; ++i) {
177  XLALFree(cache->list[i].src);
178  XLALFree(cache->list[i].dsc);
179  XLALFree(cache->list[i].url);
180  }
181  XLALFree(cache->list);
182  XLALFree(cache);
183  }
184  return;
185 }
186 
188 {
189  LALCache *duplicate = NULL;
190  if (cache) {
191  UINT4 i;
192  duplicate = XLALCreateCache(cache->length);
193  if (!duplicate)
195  for (i = 0; i < cache->length; ++i)
196  XLALCacheEntryCopy(duplicate->list + i, cache->list + i);
197  }
198  return duplicate;
199 }
200 
201 LALCache *XLALCacheMerge(const LALCache * cache1, const LALCache * cache2)
202 {
203  LALCache *cache = NULL;
204  LALCacheEntry *entry;
205  UINT4 length;
206  UINT4 i;
207  if (!cache2)
208  return XLALCacheDuplicate(cache1);
209  if (!cache1)
210  return XLALCacheDuplicate(cache2);
211  length = cache1->length + cache2->length;
212  cache = XLALCreateCache(length);
213  if (!cache)
215  entry = cache->list;
216  for (i = 0; i < cache1->length; ++i)
217  XLALCacheEntryCopy(entry++, cache1->list + i);
218  for (i = 0; i < cache2->length; ++i)
219  XLALCacheEntryCopy(entry++, cache2->list + i);
220 
221  XLALCacheSort(cache);
222  return cache;
223 }
224 
226 {
227  LALCache *cache;
228  char s[PATH_MAX + 4*(NAME_MAX + 1)];
229  int line = 0;
230  int n;
231  int i;
232  if (!fp)
235  if (n < 0)
238  cache = XLALCreateCache(n);
239  if (!cache)
241  for (i = 0; i < n; ++i)
242  if (XLALCacheFileReadRow(s, sizeof(s), fp, &line) != 1
243  || XLALCacheFileParseEntry(&cache->list[i], s) < 0) {
244  XLALDestroyCache(cache);
245  XLAL_ERROR_NULL(XLAL_EFUNC, "Error reading row %i on line %i",
246  i + 1, line);
247  }
248  XLALCacheSort(cache);
249  return cache;
250 }
251 
252 LALCache *XLALCacheImport(const char *fname)
253 {
254  LALCache *cache;
255  LALFILE *fp;
256  fp = XLALFileOpenRead(fname);
257  if (!fp)
259  cache = XLALCacheFileRead(fp);
260  XLALFileClose(fp);
261  if (!fp)
263  return cache;
264 }
265 
266 #ifdef HAVE_GLOB_H /* only use this if globbing is supported */
267 static int XLALCacheFilenameParseEntry(LALCacheEntry * entry,
268  const char *fname)
269 {
270  char path[PATH_MAX];
271  char src[NAME_MAX];
272  char dsc[NAME_MAX];
273  const char *base;
274  INT4 t0;
275  INT4 dt;
276  int c;
277 
278  /* resolve path */
279  if (!realpath(fname, path))
281 
282  /* basename */
283  base = strrchr(path, '/');
284  base = base ? base + 1 : path;
285 
286  /* construct url */
287  entry->url = XLALStringDuplicate("file://localhost");
288  if (!entry->url)
290  entry->url = XLALStringAppend(entry->url, path);
291  if (!entry->url)
293 
294  /* extract src, dsc, t0, and dt from file name */
295  c = sscanf(base, "%[a-zA-Z0-9_+#]-%[a-zA-Z0-9_+#]-%d-%d", src, dsc,
296  &t0, &dt);
297  if (c == 4) { /* expected format */
298  entry->src = XLALStringDuplicate(src);
299  entry->dsc = XLALStringDuplicate(dsc);
300  entry->t0 = t0;
301  entry->dt = dt;
302  if (!entry->src || !entry->dsc) {
303  XLALFree(entry->src);
304  XLALFree(entry->dsc);
305  XLALFree(entry->url);
307  }
308  }
309  return 0;
310 }
311 
312 #endif /* HAVE_GLOB_H */
313 
314 LALCache *XLALCacheGlob(const char *dirstr, const char *fnptrn)
315 {
316 #ifdef HAVE_GLOB_H
317  LALCache *cache;
318  int globflags = 0;
319  glob_t g;
320  size_t i;
321 
322  fnptrn = fnptrn ? fnptrn : "*";
323  dirstr = dirstr ? dirstr : ".";
324 
325  if (fnptrn[0]
326  && (fnptrn[0] == '/' || (fnptrn[0] == '.' && fnptrn[1]
327  && (fnptrn[1] == '/'
328  || (fnptrn[1] == '.'
329  && fnptrn[2] == '/')))))
330  glob(fnptrn, globflags, NULL, &g);
331  else { /* prepend path from dirname */
332  char path[PATH_MAX];
333  char dirname[PATH_MAX];
334  char *nextdir;
335  strncpy(dirname, dirstr, sizeof(dirname) - 1);
336  XLAL_LAST_ELEM(dirname) = 0;
337  do {
338  if ((nextdir = strchr(dirname, ':')))
339  *nextdir++ = 0;
340  if (snprintf(path, sizeof(path), "%s/%s", *dirname ? dirname : ".",
341  fnptrn) >= (int) sizeof(path)) {
342  globfree(&g);
343  XLAL_ERROR_NULL(XLAL_EFUNC, "path too long");
344  }
345  glob(path, globflags, NULL, &g);
346  fnptrn = path;
347  globflags |= GLOB_APPEND;
348  } while (nextdir);
349  }
350 
351  if (!g.gl_pathc) {
352  globfree(&g);
353  XLAL_ERROR_NULL(XLAL_EIO, "No matching files found in %s\n",
354  fnptrn);
355  }
356  cache = XLALCreateCache(g.gl_pathc);
357  if (!cache) {
358  globfree(&g);
360  }
361  /* copy file names */
362  for (i = 0; i < g.gl_pathc; ++i) {
363  LALCacheEntry *entry = cache->list + i;
364  if (0 > XLALCacheFilenameParseEntry(entry, g.gl_pathv[i])) {
365  globfree(&g);
366  XLALDestroyCache(cache);
368  }
369  }
370 
371  globfree(&g);
372  XLALCacheSort(cache);
373  return cache;
374 #else /* no globbing: unsupported */
375  fnptrn = NULL;
376  dirstr = NULL;
378  "Glob is unsupported on non-posix system");
379 #endif
380 }
381 
382 int XLALCacheFileWrite(LALFILE * fp, const LALCache * cache)
383 {
384 #define FS "\t" /* field separator */
385 #define RS "\n" /* record separator */
386  UINT4 i;
387  if (!fp || !cache)
389  for (i = 0; i < cache->length; ++i) {
390  LALCacheEntry *entry = cache->list + i;
391  XLALFilePrintf(fp, "%s" FS, entry->src ? entry->src : "-");
392  XLALFilePrintf(fp, "%s" FS, entry->dsc ? entry->dsc : "-");
393  if (entry->t0 > 0)
394  XLALFilePrintf(fp, "%d" FS, entry->t0);
395  else
396  XLALFilePrintf(fp, "-" FS);
397  if (entry->dt > 0)
398  XLALFilePrintf(fp, "%d" FS, entry->dt);
399  else
400  XLALFilePrintf(fp, "-" FS);
401  XLALFilePrintf(fp, "%s" RS, entry->url ? entry->url : "-");
402  }
403  return 0;
404 #undef RS
405 #undef FS
406 }
407 
408 int XLALCacheExport(const LALCache *cache, const char *fname)
409 {
410  LALFILE *fp;
411  if ((fp = XLALFileOpen(fname, "w")) == NULL)
413  if (XLALCacheFileWrite(fp, cache) < 0)
415  if (XLALFileClose(fp) < 0)
417  return 0;
418 }
419 
420 static int XLALCacheCompareSource(void UNUSED * p, const void *p1,
421  const void *p2)
422 {
423  const char *s1 = ((const struct tagLALCacheEntry *) p1)->src;
424  const char *s2 = ((const struct tagLALCacheEntry *) p2)->src;
425  return strcmp(s1 ? s1 : "", s2 ? s2 : "");
426 }
427 
428 static int XLALCacheCompareDescription(void UNUSED * p, const void *p1,
429  const void *p2)
430 {
431  const char *s1 = ((const struct tagLALCacheEntry *) p1)->dsc;
432  const char *s2 = ((const struct tagLALCacheEntry *) p2)->dsc;
433  return strcmp(s1 ? s1 : "", s2 ? s2 : "");
434 }
435 
436 static int XLALCacheCompareStartTime(void UNUSED * p, const void *p1,
437  const void *p2)
438 {
439  double t1 = ((const struct tagLALCacheEntry *) p1)->t0;
440  double t2 = ((const struct tagLALCacheEntry *) p2)->t0;
441  return (t1 > t2) - (t1 < t2);
442 }
443 
444 static int XLALCacheCompareDuration(void UNUSED * p, const void *p1,
445  const void *p2)
446 {
447  double t1 = ((const struct tagLALCacheEntry *) p1)->dt;
448  double t2 = ((const struct tagLALCacheEntry *) p2)->dt;
449  return (t1 > t2) - (t1 < t2);
450 }
451 
452 static int XLALCacheCompareEntryMetadata(void *p, const void *p1,
453  const void *p2)
454 {
455  int c;
456  if ((c = XLALCacheCompareSource(p, p1, p2)))
457  return c;
458  if ((c = XLALCacheCompareDescription(p, p1, p2)))
459  return c;
460  if ((c = XLALCacheCompareStartTime(p, p1, p2)))
461  return c;
462  return XLALCacheCompareDuration(p, p1, p2);
463 }
464 
465 
467 {
468  if (!cache)
470  /* insertion sort preserves original order in the event of a tie,
471  * allowing fail-over copies in the cache to be listed in order of
472  * preference */
473  return XLALInsertionSort(cache->list, cache->length, sizeof(*cache->list),
475 }
476 
478 {
479  LALCacheEntry *list;
480  UINT4 i, j;
481 
482  if (!cache)
484  list = cache->list;
485  i = 0;
486  for (j = 0; j < cache->length; ++j) {
487  LALCacheEntry swap;
488  swap = list[i];
489  list[i] = list[j];
490  list[j] = swap;
491  if (j + 1 == cache->length
492  || XLALCacheCompareEntryMetadata(NULL, list + i, list + j + 1))
493  ++i;
494  }
495  for (j = i; j < cache->length; ++j) {
496  XLALFree(list[j].src);
497  XLALFree(list[j].dsc);
498  XLALFree(list[j].url);
499  }
500  if (i != cache->length) {
501  cache->length = i;
502  cache->list = XLALRealloc(cache->list, i * sizeof(*cache->list));
503  if (!cache->list)
505  }
506  return 0;
507 }
508 
509 #ifdef HAVE_REGEX_H
510 static int XLALCacheEntryMatch(const LALCacheEntry * entry, INT4 t0,
511  INT4 t1, regex_t * srcreg, regex_t * dscreg,
512  regex_t * urlreg)
513 {
514  if (t1 > 0 && !(entry->t0 < t1))
515  return 0;
516  if (t0 > 0 && !(entry->t0 + entry->dt > t0))
517  return 0;
518  if (srcreg)
519  if (!entry->src || regexec(srcreg, entry->src, 0, NULL, 0))
520  return 0;
521  if (dscreg)
522  if (!entry->dsc || regexec(dscreg, entry->dsc, 0, NULL, 0))
523  return 0;
524  if (urlreg)
525  if (!entry->url || regexec(urlreg, entry->url, 0, NULL, 0))
526  return 0;
527  return 1; /* matches */
528 }
529 
530 #else /* HAVE_REGEX_H undefined */
531 /* can only attempt to match time range */
532 static int XLALCacheEntryMatchTime(const LALCacheEntry * entry, INT4 t0,
533  INT4 t1)
534 {
535  if (t1 > 0 && !(entry->t0 < t1))
536  return 0;
537  if (t0 > 0 && !(entry->t0 + entry->dt > t0))
538  return 0;
539  return 1; /* matches */
540 }
541 
542 #endif
543 
544 int XLALCacheSieve(LALCache * cache, INT4 t0, INT4 t1,
545  const char *srcregex, const char *dscregex,
546  const char *urlregex)
547 {
548  UINT4 n = 0;
549  UINT4 i;
550 #ifdef HAVE_REGEX_H
551  regex_t srcreg;
552  regex_t dscreg;
553  regex_t urlreg;
554 #else /* HAVE_REGEX_H undefined */
555  /* can only attempt to match time range */
556  if (srcregex || dscregex || urlregex) {
558  "Regular expression matching is not supported");
559  }
560 #endif
561 
562  if (!cache)
564 
565 #ifdef HAVE_REGEX_H
566  if (srcregex)
567  regcomp(&srcreg, srcregex, REG_NOSUB);
568  if (dscregex)
569  regcomp(&dscreg, dscregex, REG_NOSUB);
570  if (urlregex)
571  regcomp(&urlreg, urlregex, REG_NOSUB);
572 #endif
573 
574  for (i = 0; i < cache->length; ++i) {
575  int match;
576 #ifdef HAVE_REGEX_H
577  match =
578  XLALCacheEntryMatch(cache->list + i, t0, t1,
579  srcregex ? &srcreg : NULL,
580  dscregex ? &dscreg : NULL,
581  urlregex ? &urlreg : NULL);
582 #else
583  match = XLALCacheEntryMatchTime(cache->list + i, t0, t1);
584 #endif
585  if (match) {
586  cache->list[n++] = cache->list[i];
587  } else {
588  XLALFree(cache->list[i].src);
589  XLALFree(cache->list[i].dsc);
590  XLALFree(cache->list[i].url);
591  }
592  }
593 
594 #ifdef HAVE_REGEX_H
595  if (srcregex)
596  regfree(&srcreg);
597  if (dscregex)
598  regfree(&dscreg);
599  if (urlregex)
600  regfree(&urlreg);
601 #endif
602 
603  if (cache->length != n) {
604  cache->list = XLALRealloc(cache->list, n * sizeof(*cache->list));
605  if (n && !cache->list)
607  cache->length = n;
608  if (!n)
609  XLAL_PRINT_WARNING("No matching entries - zero-length cache");
610  }
611  return 0;
612 }
613 
614 
615 /*
616  * Binary search compare function: to locate the first entry containing the
617  * wanted time, or the first file after the requested time if the time is
618  * before the beginning or in a gap.
619  */
621  const void *first;
622  double t;
623 };
624 static int XLALCacheEntryBsearchCompare(const void *key, const void *ptr)
625 {
626  const struct LALCacheEntryBsearchKey *k = key;
627  const LALCacheEntry *entry = ptr;
628  double t = k->t;
629  /* check if requested time is after this entry */
630  if (t > entry->t0 + entry->dt)
631  return 1;
632  /* check if requested time is before this entry */
633  if (t < entry->t0) {
634  /* now we need to check:
635  * 1. is this the first file?
636  * 2. is t after the previous file, i.e., in a gap?
637  * if either of these, return 0 */
638  if (k->first == ptr || t > entry[-1].t0 + entry[-1].dt)
639  return 0;
640  return -1;
641  }
642  /* the requested time is within the bounds of this entry;
643  * but is it in the previous file too? */
644  if (k->first != ptr && t < entry[-1].t0 + entry[-1].dt)
645  return -1; /* yes it is, so this entry is _after_ the wanted entry */
646  return 0;
647 }
648 
649 /*
650  * Finds the first entry that contains the requested time, or the first entry
651  * after the time if the time is in a gap or before the first entry. Returns
652  * NULL if the time is after the last entry.
653  */
655 {
656  struct LALCacheEntryBsearchKey key;
657  key.first = cache->list;
658  key.t = t;
659  return bsearch(&key, cache->list, cache->length, sizeof(*cache->list),
661 }
662 
663 LALFILE *XLALCacheEntryOpen(const LALCacheEntry * entry)
664 {
665  char *nextslash;
666  char *nextcolon;
667  char *filename;
668  LALFILE *fp;
669  if (!entry)
671  filename = entry->url;
672  nextslash = strchr(filename, '/');
673  nextcolon = strchr(filename, ':');
674  if (nextslash && nextcolon && nextcolon < nextslash
675  && 0 == strncmp(nextcolon, "://", 3)) {
676  if (strncmp(filename, "file", nextcolon - filename))
678  "Unsupported protocol in URL %s (only file supported)",
679  entry->url);
680  filename = nextcolon + 3;
681  nextslash = strchr(filename, '/');
682  if (nextslash != filename
683  && strncmp(filename, "localhost", nextslash - filename))
685  "Cannot read files from remote host in URL %s (only localhost supported)",
686  entry->url);
687  filename = nextslash;
688  }
689  fp = XLALFileOpen(filename, "r");
690  if (!fp)
691  XLAL_ERROR_NULL(XLAL_EIO, "Could not open file %s for input",
692  filename);
693  return fp;
694 }
static char * XLALCacheFileNextField(char **ps)
Definition: LALCache.c:91
static int XLALCacheFileReadRow(char *s, size_t len, LALFILE *fp, int *line)
Definition: LALCache.c:54
static int XLALCacheCompareStartTime(void UNUSED *p, const void *p1, const void *p2)
Definition: LALCache.c:436
static int XLALCacheEntryMatchTime(const LALCacheEntry *entry, INT4 t0, INT4 t1)
Definition: LALCache.c:532
#define FS
static int XLALCacheEntryCopy(LALCacheEntry *dst, const LALCacheEntry *src)
Definition: LALCache.c:141
static int XLALCacheFileCountRows(LALFILE *fp)
Definition: LALCache.c:76
static int XLALCacheCompareSource(void UNUSED *p, const void *p1, const void *p2)
Definition: LALCache.c:420
static int XLALCacheEntryBsearchCompare(const void *key, const void *ptr)
Definition: LALCache.c:624
static int XLALCacheCompareDescription(void UNUSED *p, const void *p1, const void *p2)
Definition: LALCache.c:428
static int XLALCacheCompareDuration(void UNUSED *p, const void *p1, const void *p2)
Definition: LALCache.c:444
static int XLALCacheCompareEntryMetadata(void *p, const void *p1, const void *p2)
Definition: LALCache.c:452
#define NAME_MAX
Definition: LALCache.c:51
static int XLALCacheFileParseEntry(struct tagLALCacheEntry *entry, char *s)
Definition: LALCache.c:111
#define RS
int XLALFileClose(LALFILE *file)
Definition: FileIO.c:389
int XLALFileEOF(LALFILE *file)
Definition: FileIO.c:623
char * XLALFileGets(char *s, int size, LALFILE *file)
Definition: FileIO.c:467
LALFILE * XLALFileOpenRead(const char *path)
Definition: FileIO.c:299
int XLALFilePrintf(LALFILE *file, const char *fmt,...)
Definition: FileIO.c:515
void XLALFileRewind(LALFILE *file)
Definition: FileIO.c:577
LALFILE * XLALFileOpen(const char *path, const char *mode)
Definition: FileIO.c:370
LALCache * XLALCreateCache(UINT4 length)
Creates a LALCache structure.
Definition: LALCache.c:154
LALFILE * XLALCacheEntryOpen(const LALCacheEntry *entry)
Open a file identified by an entry in a LALCache structure.
Definition: LALCache.c:663
LALCache * XLALCacheImport(const char *fname)
Reads a LAL cache file and produces a LALCache structure.
Definition: LALCache.c:252
LALCache * XLALCacheMerge(const LALCache *cache1, const LALCache *cache2)
Returns a new LALCache structure that is the merge of two.
Definition: LALCache.c:201
void XLALDestroyCache(LALCache *cache)
Destroys a LALCache structure.
Definition: LALCache.c:172
LALCache * XLALCacheGlob(const char *dirstr, const char *fnptrn)
Globs a directory and construct LALCache from matching entries.
Definition: LALCache.c:314
LALCacheEntry * XLALCacheEntrySeek(const LALCache *cache, double t)
Finds the first entry that contains the requested time, or the first entry after the time if the time...
Definition: LALCache.c:654
int XLALCacheFileWrite(LALFILE *fp, const LALCache *cache)
Writes a LALCache structure to output LALFILE.
Definition: LALCache.c:382
LALCache * XLALCacheFileRead(LALFILE *fp)
Reads a LAL cache file and produces a LALCache structure.
Definition: LALCache.c:225
int XLALCacheUniq(LALCache *cache)
Prunes duplicate entries keeping the second one; cache is reduced in length if there are.
Definition: LALCache.c:477
int XLALCacheExport(const LALCache *cache, const char *fname)
Exports a LALCache structure to an output LAL cache file.
Definition: LALCache.c:408
int XLALCacheSort(LALCache *cache)
Sorts entries in a LALCache structure.
Definition: LALCache.c:466
int XLALCacheSieve(LALCache *cache, INT4 t0, INT4 t1, const char *srcregex, const char *dscregex, const char *urlregex)
Selects only matching entries in a LALCache structure – other entries are deleted from the LALCache s...
Definition: LALCache.c:544
LALCache * XLALCacheDuplicate(const LALCache *cache)
Duplicates a LALCache structure.
Definition: LALCache.c:187
#define XLAL_LAST_ELEM(x)
MACRO to access the last element in a fixed-size array.
uint32_t UINT4
Four-byte unsigned integer.
int32_t INT4
Four-byte signed integer.
#define XLALCalloc(m, n)
Definition: LALMalloc.h:45
#define XLALFree(p)
Definition: LALMalloc.h:47
#define XLALRealloc(p, n)
Definition: LALMalloc.h:46
char * XLALStringDuplicate(const char *s)
Like strdup but uses LAL allocation routines (free with LALFree).
Definition: LALString.c:89
char * XLALStringAppend(char *s, const char *append)
Like strcat but dynamically reallocates string with LALRealloc.
Definition: LALString.c:50
int XLALInsertionSort(void *base, size_t nobj, size_t size, void *params, int(*compar)(void *, const void *, const void *))
Definition: InsertionSort.c:37
#define XLAL_ERROR_NULL(...)
Macro to invoke a failure from a XLAL routine returning a pointer.
Definition: XLALError.h:713
#define XLAL_ERROR(...)
Macro to invoke a failure from a XLAL routine returning an integer.
Definition: XLALError.h:700
#define XLAL_PRINT_WARNING(...)
Macro that will print a warning message with a standard format.
Definition: XLALError.h:270
@ XLAL_ENOMEM
Memory allocation error.
Definition: XLALError.h:407
@ XLAL_EFAULT
Invalid pointer.
Definition: XLALError.h:408
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
Definition: XLALError.h:462
@ XLAL_EIO
I/O error.
Definition: XLALError.h:406
@ XLAL_EFAILED
Generic failure.
Definition: XLALError.h:418
def duplicate(series)
Duplicate a TimeSeries or FrequencySeries.
Definition: LALCache.c:620
double t
Definition: LALCache.c:622
const void * first
Definition: LALCache.c:621
An entry in a LAL cache.
Definition: LALCache.h:54
CHAR * src
File source field.
Definition: LALCache.h:55
CHAR * dsc
File description field.
Definition: LALCache.h:56
CHAR * url
URL of file.
Definition: LALCache.h:59
INT4 t0
GPS time (seconds) of beginning of data in file.
Definition: LALCache.h:57
INT4 dt
Duration (seconds) of data in file.
Definition: LALCache.h:58
The LALCache structure is an array of entries.
Definition: LALCache.h:63
UINT4 length
Definition: LALCache.h:64
LALCacheEntry * list
Definition: LALCache.h:65
FILE * fp
Definition: tconvert.c:105