aboutsummaryrefslogtreecommitdiff
path: root/unix/boot/mkpkg/fdcache.c
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /unix/boot/mkpkg/fdcache.c
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'unix/boot/mkpkg/fdcache.c')
-rw-r--r--unix/boot/mkpkg/fdcache.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/unix/boot/mkpkg/fdcache.c b/unix/boot/mkpkg/fdcache.c
new file mode 100644
index 00000000..7dfca1a3
--- /dev/null
+++ b/unix/boot/mkpkg/fdcache.c
@@ -0,0 +1,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);
+}