1 2 /* $Id: ndbz.h,v 1.2 1995/09/29 17:40:52 wfp5p Exp $ */ 3 4 /******************************************************************************* 5 * The Elm Mail System - $Revision: 1.2 $ $State: Exp $ 6 * 7 * Copyright (c) 1988-1995 USENET Community Trust 8 * Copyright (c) 1986,1987 Dave Taylor 9 ******************************************************************************* 10 * Bug reports, patches, comments, suggestions should be sent to: 11 * 12 * Bill Pemberton, Elm Coordinator 13 * flash@virginia.edu 14 * 15 ******************************************************************************* 16 * $Log: ndbz.h,v $ 17 * Revision 1.2 1995/09/29 17:40:52 wfp5p 18 * Alpha 8 (Chip's big changes) 19 * 20 * Revision 1.1.1.1 1995/04/19 20:38:30 wfp5p 21 * Initial import of elm 2.4 PL0 as base for elm 2.5. 22 * 23 ******************************************************************************/ 24 25 /** define file for ndbz for mail system. **/ 26 27 /* 28 * Stdio buffer for .pag reads. Buffering more than about 16 does not help 29 * significantly at the densities we try to maintain, and the much larger 30 * buffers that most stdios default to are much more expensive to fill. 31 * With small buffers, stdio is performance-competitive with raw read(), 32 * and it's much more portable. 33 */ 34 #ifndef NPAGBUF 35 #define NPAGBUF 16 36 #endif 37 38 /* 39 * Stdio buffer for base-file reads. 40 */ 41 #ifndef SHISTBUF 42 #define SHISTBUF 512 43 #endif 44 45 /* for dbz and ndbz */ 46 typedef struct { 47 char *dptr; 48 size_t dsize; 49 } datum; 50 51 /* 52 * ANSI C says an offset into a file is a long, not an off_t, for some 53 * reason. This actually does simplify life a bit, but it's still nice 54 * to have a distinctive name for it. Beware, this is just for readability, 55 * don't try to change this. 56 */ 57 58 /* 59 * Big kludge: this is set up as 32-bit rather than a long so that ndbz db's 60 * will work across NFS on 64 bit machines as well as 32 bit machines. 61 */ 62 63 #define of_t int32 64 #define SOF (sizeof(of_t)) 65 66 /* 67 * We read configuration info from the .dir file into this structure, 68 * so we can avoid wired-in assumptions for an existing database. 69 * 70 * Among the info is a record of recent peak usages, so that a new table 71 * size can be chosen intelligently when rebuilding. 10 is a good 72 * number of usages to keep, since news displays marked fluctuations 73 * in volume on a 7-day cycle. 74 */ 75 struct dbzconfig { 76 int olddbz; /* .dir file empty but .pag not? */ 77 of_t tsize; /* table size */ 78 # ifndef NMEMORY 79 # define NMEMORY 10 /* # days of use info to remember */ 80 # endif 81 # define NUSEDS (1+NMEMORY) 82 of_t used[NUSEDS]; /* entries used today, yesterday, ... */ 83 int valuesize; /* size of table values, == SOF */ 84 int bytemap[SOF]; /* byte-order map */ 85 char casemap; /* case-mapping algorithm (see cipoint()) */ 86 char fieldsep; /* field separator in base file, if any */ 87 of_t tagenb; /* unshifted tag-enable bit */ 88 of_t tagmask; /* unshifted tag mask */ 89 int tagshift; /* shift count for tagmask and tagenb */ 90 }; 91 92 /* 93 * Data structure for recording info about searches. 94 */ 95 struct searcher { 96 of_t place; /* current location in file */ 97 int tabno; /* which table we're in */ 98 int run; /* how long we'll stay in this table */ 99 long hash; /* the key's hash code (for optimization) */ 100 of_t tag; /* tag we are looking for */ 101 int seen; /* have we examined current location? */ 102 int aborted; /* has i/o error aborted search? */ 103 }; 104 typedef struct dbz { 105 FILE *dbz_basef; /* descriptor for base file */ 106 char *dbz_basefname; /* name for not-yet-opened base file */ 107 FILE *dbz_dirf; /* descriptor for .dir file */ 108 int dbz_dirronly; /* dirf open read-only? */ 109 FILE *dbz_pagf; /* descriptor for .pag file */ 110 of_t dbz_pagpos; /* posn in pagf; only search may set != -1 */ 111 int dbz_pagronly; /* pagf open read-only? */ 112 of_t *dbz_corepag; /* incore version of .pag file, if any */ 113 FILE *dbz_bufpagf; /* well-buffered pagf, for incore rewrite */ 114 of_t dbz_tagbits; /* pre-shifted tag mask */ 115 of_t dbz_taghere; /* pre-shifted tag-enable bit */ 116 of_t dbz_tagboth; /* tagbits|taghere */ 117 struct dbzconfig dbz_conf; 118 int dbz_incore; 119 of_t dbz_pagbuf[NPAGBUF]; 120 char dbz_basebuf[SHISTBUF]; 121 struct searcher dbz_srch; 122 struct searcher *dbz_prevp; /* &srch or FRESH */ 123 int dbz_mybmap[SOF]; /* my byte order (see mybytemap()) */ 124 int dbz_bytesame; /* is database order same as mine? */ 125 int dbz_debug; /* controlled by dbzdebug() */ 126 int dbz_written; /* has a store() been done? */ 127 } DBZ; 128 129 /* FOO - should these declarations be ANSIfied? */ 130 131 /* standard dbz functions */ 132 extern DBZ *dbz_open(); 133 extern datum dbz_fetch(); 134 extern int dbz_store(); 135 extern int dbz_delete(); /* not in dbz */ 136 extern datum dbz_firstkey(); /* not in dbz */ 137 extern datum dbz_nextkey(); /* not in dbz */ 138 extern int dbz_close(); /* in dbz, but not in old dbm */ 139 140 /* new stuff for dbz */ 141 extern DBZ *dbz_fresh(); 142 extern DBZ *dbz_again(); 143 extern int dbz_sync(); 144 extern long dbz_size(); 145 extern int dbz_incore(); 146 extern int dbz_cancel(); 147 extern int dbz_debug(); 148 149 /* 150 * In principle we could handle unlimited-length keys by operating a chunk 151 * at a time, but it's not worth it in practice. Setting a nice large 152 * bound on them simplifies the code and doesn't hurt anything. 153 */ 154 #define DBZMAXKEY 255 155