1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*
* FDCACHE -- Maintain a cache of filenames and their associated modification
* dates. This can greatly reduce the amount of time required to determine
* which, if any, of the modules in a library need updating because an include
* file they depend upon has been modified.
*
* External entry points:
*
* l = m_fdate (fname) # return file (modification) date
* m_fdinit (debug) # initialize cache
*/
#define MAX_FILES 20 /* size of the cache */
#define SZ_NAME 32 /* size of filename slot */
#define EOS '\0'
struct _fdate { /* cache list element structure */
struct _fdate *uplnk;
struct _fdate *dnlnk;
int nrefs; /* number of references */
int chksum; /* speeds searches */
long fdate; /* file modification date */
char fname[SZ_NAME+1]; /* file name */
};
struct _fdate fdcache[MAX_FILES]; /* the cache */
struct _fdate *fd_head; /* doubly linked list */
struct _fdate *fd_tail;
int fd_hits, fd_misses;
struct _fdate *fd_unlink();
struct _fdate *fd_tohead();
struct _fdate *fd_totail();
long m_fdate (char *fname);
void m_fdinit (int debug);
int fd_chksum (char *s);
extern long os_fdate (char *fname);
/* M_FDATE -- Get file modification date. This is functionally equivalent to
* os_fdate().
*/
long
m_fdate (char *fname)
{
register struct _fdate *fd;
register int chksum;
/* Look in the cache first.
*/
chksum = fd_chksum (fname);
for (fd=fd_head; fd != NULL; fd=fd->dnlnk)
if (fd->chksum == chksum && strcmp (fname, fd->fname) == 0) {
fd_tohead (fd_unlink (fd));
fd->nrefs++;
fd_hits++;
return (fd->fdate);
}
/* Cache miss. Don't put in cache it name is too long.
*/
fd_misses++;
if (strlen (fname) > SZ_NAME)
return (os_fdate (fname));
/* Put fname in the cache. Reuse slot at tail of list.
*/
fd = fd_tohead (fd_unlink (fd_tail));
strncpy (fd->fname, fname, SZ_NAME);
fd->chksum = fd_chksum (fname);
fd->fdate = os_fdate (fname);
fd->nrefs = 1;
return (fd->fdate);
}
/* M_FDINIT -- Initialize (clear) the fdate cache.
*/
void
m_fdinit (int debug)
{
register struct _fdate *fd;
register int i;
int total;
if (debug) {
total = fd_hits + fd_misses;
printf ("file date cache: %d hits, %d misses, %d%% of %d\n",
fd_hits, fd_misses, (total ? fd_hits * 100 / total : 0), total);
for (fd=fd_head; fd != NULL; fd=fd->dnlnk)
if (fd->fname[0])
printf ("%3d %10ld (%05d) %s\n",
fd->nrefs, fd->fdate, fd->chksum, fd->fname);
fd_hits = 0;
fd_misses = 0;
fflush (stdout);
}
fd = fd_head = fd_tail = &fdcache[0];
fd->uplnk = NULL;
fd->dnlnk = NULL;
fd->nrefs = 0;
fd->chksum = -1;
fd->fname[0] = EOS;
for (i=1; i < MAX_FILES; i++) {
fd = fd_tohead (&fdcache[i]);
fd->fname[0] = EOS;
fd->chksum = -1;
fd->nrefs = 0;
}
}
/* FD_TOHEAD -- Link a fdate struct at the head of the list.
*/
struct _fdate *
fd_tohead (register struct _fdate *fd)
{
if (fd != fd_head) {
fd->uplnk = NULL;
fd->dnlnk = fd_head;
fd_head->uplnk = fd;
fd_head = fd;
}
return (fd);
}
/* FD_TOTAIL -- Link a fdate struct at the tail of the list.
*/
struct _fdate *
fd_totail (register struct _fdate *fd)
{
if (fd != fd_tail) {
fd->uplnk = fd_tail;
fd->dnlnk = NULL;
fd_tail->dnlnk = fd;
fd_tail = fd;
}
return (fd);
}
/* FD_UNLINK -- Unlink an fdate struct.
*/
struct _fdate *
fd_unlink (register struct _fdate *fd)
{
if (fd == fd_head)
fd_head = fd->dnlnk;
if (fd == fd_tail)
fd_tail = fd->uplnk;
if (fd->uplnk)
fd->uplnk->dnlnk = fd->dnlnk;
if (fd->dnlnk)
fd->dnlnk->uplnk = fd->uplnk;
return (fd);
}
/* FD_CHKSUM -- Compute the checksum of a character string.
*/
int
fd_chksum (char *s)
{
register int sum=0;
while (*s)
sum += *s++;
return (sum);
}
|