StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
cache.c
1 /*
2  cache.c
3  caching of tensor coefficients in
4  dynamically allocated memory
5  this file is part of LoopTools
6  last modified 27 Jun 04 th
7 */
8 
9 
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 
14 
15 #ifdef HAVE_UNDERSCORE
16 #define cachelookup cachelookup_
17 #define setcachelast setcachelast_
18 #define getcachelast getcachelast_
19 #endif
20 
21 
22 #ifndef REALSIZE
23 #define REALSIZE sizeof(double)
24 #endif
25 
26 #define CPLXSIZE (2*REALSIZE)
27 
28 #define ptrdiff(a, b) (long)((char *)a - (char *)b)
29 
30 
31 int cachelookup(char *para, char **base,
32  void (*calc)(char *, char *), int *npara, int *nval)
33 {
34  char *node, *last, **next = base;
35  const int parasize = *npara*REALSIZE;
36  const int valsize = *nval*CPLXSIZE;
37 
38  last = *(base + 1);
39  if( last ) {
40  do {
41  node = *next;
42  next = (char **)(node - sizeof(char *));
43  if( memcmp(para, node + valsize, parasize) == 0 ) goto done;
44  } while( node != last );
45  }
46  node = *next;
47  if( node == NULL ) {
48  node = malloc(sizeof(char *) + valsize + parasize + CPLXSIZE);
49  /* MUST have extra CPLXSIZE for alignment so that node
50  can be reached with an integer offset into base */
51  if( node == NULL ) {
52  fputs("Out of cache memory.\n", stderr);
53  exit(1);
54  }
55  node += sizeof(char *);
56  node += ptrdiff(base, node) & (CPLXSIZE - 1);
57  *next = node;
58  *(char **)(node - sizeof(char *)) = NULL;
59  }
60  *(base + 1) = node;
61  memcpy(node + valsize, para, parasize);
62  calc(para, node);
63 done:
64  return ptrdiff(node, base)/CPLXSIZE;
65 }
66 
67 
68 void setcachelast(char **base, int *offset)
69 {
70  *(base + 1) = *offset ? (char *)base + *offset*CPLXSIZE : NULL;
71 }
72 
73 
74 int getcachelast(char **base)
75 {
76  return *(base + 1) ? ptrdiff(*(base + 1), base)/CPLXSIZE : 0;
77 }
78