diff options
Diffstat (limited to 'z47.c')
-rw-r--r-- | z47.c | 250 |
1 files changed, 250 insertions, 0 deletions
@@ -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 |