00001 00002 /* */ 00003 /* Copyright 1984,1985,1986,1988,1989,1990,2003 by Howard Turtle */ 00004 /* */ 00005 00006 #define max_long 2147483647 00007 #define keyf 32472 /* marker for fcb */ 00008 #define current_version 4 /* version of keyed file software */ 00009 #define max_key_lc 82 /* maximum key length */ 00010 #define key_ptrs_per_block 506 /* number of key_ptrs in index block */ 00011 #define random_split_lc 880 /* chars to be freed on random split */ 00012 #define level_zero 0 /* level of index leaves */ 00013 #define level_one 1 /* level immediately above leaves */ 00014 #define long_lc sizeof(long) /* lc of a long int */ 00015 #define min_buffer_cnt 3 /* default number of buffers allocated */ 00016 #define max_buffer_cnt 1024 /* max buffers allowed */ 00017 #define buf_hash_load_factor 3 /* hash table is>=this times buffers alloc,*/ 00018 #define max_level 32 /* number of index block levels */ 00019 #define max_char '\377' 00020 #define fib_lc min_fcb_lc-(min_buffer_cnt*buffer_lc) /* length of fib */ 00021 #define max_segment_lc max_long /* max length of a file segment */ 00022 #define max_segments 1024 /* max number of file segments */ 00023 #define max_files 10 /* max number of open files */ 00024 /*POSIX VALUES HERE?!? was 82, 40*/ 00025 #define max_filename_lc 245 /* max length of a file name -10 for init_filename HACK! */ 00026 #define max_extension_lc 40 /* max length of file name extension unused?!? */ 00027 enum file_access {random,seq}; 00028 enum comparison {less,equal,greater}; 00029 00030 struct key { 00031 unsigned char 00032 text[max_key_lc]; 00033 short 00034 lc; 00035 }; 00036 00037 struct leveln_pntr{ 00038 int 00039 segment; 00040 long 00041 block; 00042 }; 00043 #define leveln_lc sizeof(struct leveln_pntr) 00044 00045 struct level0_pntr { 00046 int 00047 segment; 00048 long 00049 sc, 00050 lc; 00051 }; 00052 #define level0_lc sizeof(struct level0_pntr) 00053 00054 struct key_ptr_t { 00055 short 00056 sc, /* start character of key */ 00057 lc; /* lc of key, does not include pointer */ 00058 }; 00059 #define key_ptr_lc sizeof(struct key_ptr_t) 00060 #define keyspace_lc (key_ptr_lc*key_ptrs_per_block) 00061 00062 struct block { /* block is the disk resident image of */ 00063 short /* an index block */ 00064 keys_in_block, 00065 chars_in_use, /* chars in key/pointer pool, does not */ 00066 /* include length of key_ptr_t entries */ 00067 level; 00068 struct leveln_pntr 00069 next,prev; 00070 struct key_ptr_t /* key_ptrs are inserted from 0, keys and */ 00071 keys[key_ptrs_per_block]; /* file pointers overlay the top end */ 00072 }; 00073 #define block_lc sizeof(struct block) 00074 00075 /* Buffer handling. Buffers contain the disk image of an index block */ 00076 /* together with additional information. A hashing technique is */ 00077 /* used to find a buffer that holds a given block. A hash table is */ 00078 /* allocated as the last buffers in the fcb of roughly three times */ 00079 /* the number of buffers allocated. buf_hash_table[k] contains the */ 00080 /* index of the first buffer containing a block whose hash value is */ 00081 /* k. If there are multiple buffers containing blocks with hash */ 00082 /* value k then they are linked using hash_next. */ 00083 00084 struct buffer_type { /* buffer is the memory resident image of */ 00085 boolean /* an index block */ 00086 locked, 00087 modified; 00088 int 00089 older, /* index to prev element in LRU list */ 00090 younger, /* index to next element in LRU list */ 00091 hash_next; 00092 struct leveln_pntr 00093 contents; /* block in buffer, nulln_ptr if empty */ 00094 struct block 00095 b; 00096 }; 00097 #define buffer_lc sizeof(struct buffer_type) 00098 #define hash_entries_per_buf (buffer_lc / sizeof(int)) 00099 00100 /* Segment handling. A keyed file consist of one or more component files */ 00101 /* called segments. Segment 0 contains the file information block and */ 00102 /* is alway present. Additional segments are created as needed with */ 00103 /* a suffix of "$n" appended to the base file name where n is the */ 00104 /* segment number. The file information block contains a segment_cnt */ 00105 /* and a list of each segment_length. After open the fcb contains a */ 00106 /* list of the file number on which each segment is open (max_files */ 00107 /* implies not open) in segment_ix */ 00108 00109 /* File handling. Up to max_files files may be open at one time. */ 00110 /* open_file_cnt is the number of files actually open, open_file[] is */ 00111 /* a list of file_indexes in use, file_age[] is the age of each open */ 00112 /* file, open_segment[] is the segment to which the file is open */ 00113 00114 struct fcb { 00115 00116 int 00117 error_code, 00118 version, /* version of keyed file manager */ 00119 segment_cnt, /* number of segments in use */ 00120 primary_level; /* level of primary index block */ 00121 boolean 00122 file_ok; 00123 long 00124 marker; 00125 struct leveln_pntr 00126 first_at_level[max_level]; /* block containing lowest key at level */ 00127 long 00128 segment_length[max_segments];/* length in bytes of each segment */ 00129 char 00130 file_name[max_filename_lc], 00131 file_extension[max_extension_lc]; 00132 00133 /* start of temporary information */ 00134 00135 enum file_access 00136 insert_mode; /* random or sequential inserts */ 00137 int 00138 open_file_cnt, /* number of files actually open */ 00139 open_segment[max_files], /* segment to which each file is open */ 00140 file_age[max_files], /* age of each open file */ 00141 oldest_buffer, /* first buffer in LRU buffer list */ 00142 youngest_buffer; /* last buffer in LRU buffer list */ 00143 FILE 00144 *open_file[max_files]; /* pointers to open files */ 00145 00146 int 00147 segment_ix[max_segments], /* index into open_file[] if segment open */ 00148 position_ix, /* posn. in level0 blk of last retrieval */ 00149 current_age, /* age of file pool (0..maxint)*/ 00150 buffers_allocated, /* number of buffers actually allocated */ 00151 buffers_in_use, /* buffers actually used */ 00152 *buf_hash_table, /* pointer to base of buffer hash table */ 00153 buf_hash_entries; /* size of buf_hash_table */ 00154 struct leveln_pntr 00155 mru_at_level[max_level], /* most recently used block at each level*/ 00156 position; /* level0 block of last retrieval */ 00157 struct buffer_type 00158 buffer[min_buffer_cnt]; /* should be at end of fcb so we can extend */ 00159 }; 00160 #define min_fcb_lc sizeof(struct fcb)