aboutsummaryrefslogtreecommitdiffstats
path: root/z47.c
diff options
context:
space:
mode:
Diffstat (limited to 'z47.c')
-rw-r--r--z47.c250
1 files changed, 250 insertions, 0 deletions
diff --git a/z47.c b/z47.c
new file mode 100644
index 0000000..2fac7b8
--- /dev/null
+++ b/z47.c
@@ -0,0 +1,250 @@
+/*@z47.c:Environment Table:EnvReadRetrieve()@*********************************/
+/* */
+/* THE LOUT DOCUMENT FORMATTING SYSTEM (VERSION 3.17) */
+/* COPYRIGHT (C) 1991, 1999 Jeffrey H. Kingston */
+/* */
+/* Jeffrey H. Kingston (jeff@cs.usyd.edu.au) */
+/* Basser Department of Computer Science */
+/* The University of Sydney 2006 */
+/* AUSTRALIA */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either Version 2, or (at your option) */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA */
+/* */
+/* FILE: z47.c */
+/* MODULE: Environment Table */
+/* EXTERNS: EnvInit(), EnvWriteRetrieve(), EnvWriteInsert(), */
+/* EnvReadRetrieve(), EnvReadInsert() */
+/* */
+/*****************************************************************************/
+#include "externs.h"
+#define TAB_SIZE 211
+#define MAX_CACHE 180
+
+#define env_offset(x) back(x, ROWM)
+#define env_lnum(x) line_num(fpos(x))
+#define env_fnum(x) file_num(fpos(x))
+#define env_read(x) sized(x)
+
+static OBJECT env_cache; /* cache of envts in use */
+static int cache_count; /* current size of cache */
+static int stat_writes; /* calls to WriteRetrieve */
+static int stat_write_hits; /* hits in WriteRetrieve */
+static int stat_reads; /* calls to ReadRetrieve */
+static int stat_read_hits; /* hits in ReadRetrieve */
+
+static OBJECT tab[TAB_SIZE];
+
+#define hash1(pos, env, fnum) \
+{ \
+ pos = ( (int) env + fnum ) % TAB_SIZE; \
+}
+
+#define hash2(pos, fnum, offset) \
+{ \
+ pos = ( offset + fnum ) % TAB_SIZE; \
+}
+
+
+/*****************************************************************************/
+/* */
+/* void EnvInit(void) */
+/* */
+/* Initialize this module. */
+/* */
+/*****************************************************************************/
+
+void EnvInit(void)
+{ int i;
+ debug0(DET, DD, "EnvInit()");
+ stat_reads = 0;
+ stat_read_hits = 0;
+ stat_writes = 0;
+ stat_write_hits = 0;
+ New(env_cache, ACAT);
+ cache_count = 0;
+ for( i = 0; i < TAB_SIZE; i++ )
+ { tab[i] = nilobj;
+ }
+ debug0(DET, DD, "EnvInit returning");
+} /* end EnvInit */
+
+
+/*****************************************************************************/
+/* */
+/* BOOLEAN EnvWriteRetrieve(OBJECT env, FILE_NUM fnum, int *offset, *lnum) */
+/* */
+/* Return the offset in file fnum where environment env has been written, */
+/* or FALSE if env has not been written to this file. */
+/* */
+/*****************************************************************************/
+
+BOOLEAN EnvWriteRetrieve(OBJECT env, FILE_NUM fnum, int *offset, int *lnum)
+{ int pos; OBJECT link, y, z;
+ debug2(DET, DD, "EnvWriteRetrieve(env %d, %s)", (int) env, FileName(fnum));
+ debug1(DET, DDD, " %s", EchoObject(env));
+ stat_writes++;
+ hash1(pos, env, fnum);
+ if( tab[pos] != nilobj )
+ {
+ for( link = Down(tab[pos]); link != tab[pos]; link = NextDown(link) )
+ { Child(y, link);
+ Child(z, Down(y));
+ if( env_fnum(y) == fnum && z == env && !env_read(y) )
+ { MoveLink(LastUp(y), env_cache, PARENT);
+ *offset = env_offset(y);
+ *lnum = env_lnum(y);
+ stat_write_hits++;
+ debug2(DET, DD, "EnvWriteRetrieve returning TRUE (offset %d, lnum %d)",
+ *offset, *lnum);
+ return TRUE;
+ }
+ }
+ }
+ debug0(DET, DD, "EnvWriteRetrieve returning FALSE");
+ return FALSE;
+} /* end EnvWriteRetrieve */
+
+
+/*****************************************************************************/
+/* */
+/* void EnvWriteInsert(OBJECT env, FILE_NUM fnum, int offset, int lnum) */
+/* */
+/* Record the fact that environment env has been written to file fnum */
+/* at the given offset. */
+/* */
+/*****************************************************************************/
+
+void EnvWriteInsert(OBJECT env, FILE_NUM fnum, int offset, int lnum)
+{ int pos; OBJECT loser, x;
+ debug3(DET, DD, "EnvWriteInsert(env %d, %s, %d)", (int) env,
+ FileName(fnum), offset);
+
+ /* to limit the cache size, remove least recently used entry if full */
+ if( cache_count >= MAX_CACHE )
+ {
+ Child(loser, Down(env_cache));
+ DeleteLink(Up(loser));
+ DisposeChild(Up(loser));
+ cache_count--;
+ }
+
+ /* insert the new entry */
+ hash1(pos, env, fnum);
+ if( tab[pos] == nilobj ) New(tab[pos], ACAT);
+ New(x, ACAT);
+ env_fnum(x) = fnum;
+ env_offset(x) = offset;
+ env_lnum(x) = lnum;
+ env_read(x) = FALSE;
+ Link(tab[pos], x);
+ Link(env_cache, x);
+ Link(x, env);
+ cache_count++;
+
+ debug1(DET, DD, "EnvWriteInsert returning (cache_count = %d)", cache_count);
+} /* end EnvWriteInsert */
+
+
+/*****************************************************************************/
+/* */
+/* BOOLEAN EnvReadRetrieve(FILE_NUM fnum, int offset, OBJECT *env) */
+/* */
+/* Return the environment that appears in file fnum at the given offset, */
+/* or FALSE if this is not currently known. */
+/* */
+/*****************************************************************************/
+
+BOOLEAN EnvReadRetrieve(FILE_NUM fnum, int offset, OBJECT *env)
+{ int pos; OBJECT link, y, z;
+ debug2(DET, DD, "EnvReadRetrieve(%s, %d)", FileName(fnum), offset);
+ stat_reads++;
+
+ hash2(pos, fnum, offset);
+ if( tab[pos] != nilobj )
+ {
+ for( link = Down(tab[pos]); link != tab[pos]; link = NextDown(link) )
+ { Child(y, link);
+ Child(z, Down(y));
+ if( env_fnum(y) == fnum && env_offset(y) == offset && env_read(y) )
+ { MoveLink(LastUp(y), env_cache, PARENT);
+ Child(*env, Down(y));
+ stat_read_hits++;
+ debug1(DET, DD, "EnvReadRetrieve returning env %d", (int) *env);
+ return TRUE;
+ }
+ }
+ }
+ debug0(DET, DD, "EnvReadRetrieve returning FALSE");
+ return FALSE;
+} /* end EnvReadRetrieve */
+
+
+/*****************************************************************************/
+/* */
+/* void EnvReadInsert(FILE_NUM fnum, int offset, OBJECT env) */
+/* */
+/* Record the fact that environment env has just been read from file fnum */
+/* at position offset. */
+/* */
+/*****************************************************************************/
+
+void EnvReadInsert(FILE_NUM fnum, int offset, OBJECT env)
+{ int pos; OBJECT x, loser;
+ debug3(DET, DD, "EnvReadInsert(%s, %d, env %d)",
+ FileName(fnum), offset, (int) env);
+
+ /* to limit the cache size, remove least recently used entry if full */
+ if( cache_count >= MAX_CACHE )
+ {
+ Child(loser, Down(env_cache));
+ DeleteLink(Up(loser));
+ DisposeChild(Up(loser));
+ cache_count--;
+ }
+
+ /* insert the new entry */
+ hash2(pos, fnum, offset);
+ if( tab[pos] == nilobj ) New(tab[pos], ACAT);
+ New(x, ACAT);
+ env_fnum(x) = fnum;
+ env_offset(x) = offset;
+ env_read(x) = TRUE;
+ Link(tab[pos], x);
+ Link(env_cache, x);
+ Link(x, env);
+ cache_count++;
+
+ debug1(DET, DD, "EnvReadInsert returning (cache_count = %d)", cache_count);
+} /* end EnvReadInsert */
+
+
+#if DEBUG_ON
+/*****************************************************************************/
+/* */
+/* void EnvDebug() */
+/* */
+/* Debug statistics of this module's performance. */
+/* */
+/*****************************************************************************/
+
+void EnvDebug(void)
+{
+ debug3(DET, D, "Env Table %6s %6s %6s", "calls", "hits", "% hits");
+ debug3(DET, D, "reading %6d %6d %6.1f", stat_reads, stat_read_hits,
+ stat_reads == 0 ? (float) 0 : (float) 100 * stat_read_hits / stat_reads);
+ debug3(DET, D, "writing %6d %6d %6.1f", stat_writes, stat_write_hits,
+ stat_writes == 0 ? (float) 0 : (float) 100 * stat_write_hits / stat_writes);
+} /* end EnvDebug */
+#endif