@@ -38,19 +38,11 @@ DBM_HDR = RECORD
3838 root : LONGINT;
3939 size : WORD;
4040END ;
41- DBM_REC = RECORD
42- next : LONGINT;
43- size : WORD;
44- END ;
4541
4642DBMFile = RECORD
4743 f : BFILE;
4844 header : DBM_HDR;
49- crec : DBM_REC;
50- crecno : LONGINT;
51- needupdate : BOOLEAN;
5245 rblk_size : WORD;
53- data : PCHAR;
5446END ;
5547
5648PROCEDURE dbm_reset (VAR f : DBMFile; fname : STRING; blk_size : WORD);
@@ -75,36 +67,22 @@ IMPLEMENTATION
7567
7668CONST
7769DBM_SIGN = $4D44;
70+ ADDED_DATA = SizeOf(LONGINT) + SizeOf(WORD);
7871
7972FUNCTION norm_blk_size (blk_size : WORD) : WORD;
8073BEGIN
81- blk_size := blk_size + SizeOf(DBM_REC) ;
74+ blk_size := blk_size + ADDED_DATA ;
8275 IF blk_size < SizeOf(DBM_HDR) THEN blk_size := SizeOf(DBM_HDR);
8376 IF (blk_size AND 3 ) <> 0 THEN blk_size := ((blk_size SHR 2 ) + 1 ) SHL 2 ;
8477 norm_blk_size := blk_size;
8578END ;
8679
87- PROCEDURE dbm_update (VAR f : DBMFile);
88- BEGIN
89- IF (f.needupdate) AND (f.crecno <> 0 ) THEN BEGIN
90- Seek(f.f, f.crecno * f.header.size);
91- BlockWrite(f.f, f.crec, SizeOf(DBM_REC));
92- BlockWrite(f.f, f.data^, f.rblk_size);
93- END ;
94- f.needupdate := FALSE;
95- END ;
96-
97- PROCEDURE dbm_go (VAR f : DBMFile; recno : LONGINT);
80+ FUNCTION dbm_go (VAR f : DBMFile; recno : LONGINT) : LONGINT;
81+ VAR r : LONGINT;
9882BEGIN
99- IF recno = f.crecno THEN EXIT;
100- dbm_update(f);
101- { FillChar(f.data^, f.rblk_size, #0); }
102- f.crec.next := 0 ;
103- f.crec.size := 0 ;
104- f.crecno := recno;
105- Seek(f.f, recno * f.header.size);
106- BlockRead(f.f, f.crec, SizeOf(DBM_REC));
107- BlockRead(f.f, f.data^, f.rblk_size);
83+ r := recno * f.header.size;
84+ Seek(f.f, r);
85+ dbm_go := r;
10886END ;
10987
11088PROCEDURE dbm_reset (VAR f : DBMFile; fname : STRING; blk_size : WORD);
@@ -119,30 +97,24 @@ BEGIN
11997 Close(f.f);
12098 dbm_rewrite(f, fname, blk_size);
12199 END ELSE IF (f.header.sign = DBM_SIGN) AND (f.header.size = rblk_size) THEN BEGIN
122- f.rblk_size := f.header.size - SizeOf(DBM_REC);
123- GetMem(f.data, f.rblk_size);
124- FillChar(f.data^, f.rblk_size, #0 );
100+ f.rblk_size := f.header.size - ADDED_DATA;
125101 END ELSE BEGIN
126102 Close(f.f);
127103 dbm_rewrite(f, fname, blk_size);
128104 END ;
129105END ;
130106
131107PROCEDURE _dbm_rewrite (VAR f : DBMFile);
108+ VAR i : INTEGER;
132109BEGIN
133110 IF IsOpen(f.f) THEN BEGIN
134111 f.header.sign := DBM_SIGN;
135112 f.header.next := 0 ;
136113 f.header.records := 0 ;
137114 f.header.root := 0 ;
138- f.crecno := 0 ;
139- f.needupdate := FALSE;
140- FillChar(f.crec, SizeOf(DBM_REC), #0 );
141- GetMem(f.data, f.rblk_size);
142- FillChar(f.data^, f.rblk_size, #0 );
143115 Seek(f.f, 0 );
144116 BlockWrite(f.f, f.header, SizeOf(DBM_HDR));
145- BlockWrite(f.f, f.data^, f.header.size - SizeOf(DBM_HDR));
117+ FOR i := 1 TO f.header.size - SizeOf(DBM_HDR) DO WriteByte(f.f, 0 );
146118 END ;
147119END ;
148120
@@ -152,7 +124,7 @@ BEGIN
152124 Assign(f.f, fname);
153125 ReWrite(f.f);
154126 f.header.size := norm_blk_size(blk_size);
155- f.rblk_size := f.header.size - SizeOf(DBM_REC) ;
127+ f.rblk_size := f.header.size - ADDED_DATA ;
156128 _dbm_rewrite(f);
157129END ;
158130
@@ -161,7 +133,7 @@ BEGIN
161133 FillChar(f, SizeOf(DBMFile), #0 );
162134 ReWriteTemp(f.f);
163135 f.header.size := norm_blk_size(blk_size);
164- f.rblk_size := f.header.size - SizeOf(DBM_REC) ;
136+ f.rblk_size := f.header.size - ADDED_DATA ;
165137 _dbm_rewrite(f);
166138END ;
167139
@@ -173,11 +145,9 @@ END;
173145PROCEDURE dbm_close (VAR f : DBMFile);
174146BEGIN
175147 IF NOT IsOpen(f.f) THEN EXIT;
176- dbm_update(f);
177148 Seek(f.f, 0 );
178149 BlockWrite(f.f, f.header, SizeOf(DBM_HDR));
179150 Close(f.f);
180- IF f.data <> NIL THEN FreeMem(f.data, f.rblk_size);
181151 FillChar(f, SizeOf(DBMFile), #0 );
182152END ;
183153
@@ -187,12 +157,11 @@ BEGIN
187157 IF NOT IsOpen(f.f) THEN EXIT;
188158 WHILE rec <> 0 DO BEGIN
189159 dbm_go(f, rec);
190- n := f.crec.next ;
191- f.crec.next := f.header.next ;
192- f.crec.size := 0 ;
193- f.needupdate := TRUE ;
160+ n := ReadDWord(f.f) ;
161+ dbm_go(f, rec) ;
162+ WriteDWord(f.f, f.header.next) ;
163+ WriteWord(f.f, 0 ) ;
194164 f.header.next := rec;
195- FillChar(f.data^, f.rblk_size, #0 );
196165 rec := n;
197166 END ;
198167END ;
@@ -203,15 +172,12 @@ BEGIN
203172 IF f.header.next <> 0 THEN BEGIN
204173 r := f.header.next;
205174 dbm_go(f, r);
206- f.header.next := f.crec.next ;
175+ f.header.next := ReadDWord(f.f) ;
207176 END ELSE BEGIN
208177 Inc(f.header.records);
209178 r := f.header.records;
210179 END ;
211180 dbm_go(f, r);
212- f.crec.next := 0 ;
213- f.crec.size := 0 ;
214- f.needupdate := TRUE;
215181 dbm_alloc := r;
216182END ;
217183
@@ -222,8 +188,8 @@ BEGIN
222188 IF IsOpen(f.f) THEN BEGIN
223189 WHILE rec <> 0 DO BEGIN
224190 dbm_go(f, rec);
225- Inc(r, f.crec.size );
226- rec := f.crec.next ;
191+ rec := ReadDWord(f.f );
192+ Inc(r, ReadWord(f.f)) ;
227193 END ;
228194 END ;
229195 dbm_size := r;
@@ -237,19 +203,20 @@ BEGIN
237203 p := @b;
238204 WHILE (size <> 0 ) AND (rec <> 0 ) DO BEGIN
239205 dbm_go(f, rec);
240- g := f.crec.size;
206+ rec := ReadDWord(f.f);
207+ g := ReadWord(f.f);
241208 IF g > size THEN g := size;
242- Move (f.data^ , p^, g);
209+ BlockRead (f.f , p^, g);
243210 Dec(size, g);
244211 Inc(p, g);
245- rec := f.crec.next;
246212 END ;
247213END ;
248214
249215FUNCTION dbm_add (VAR f : DBMFile; VAR b; size : WORD) : LONGINT;
250216VAR root, prec, crec : LONGINT;
251217 p : PCHAR;
252218 csize : WORD;
219+ i : INTEGER;
253220BEGIN
254221 root := 0 ;
255222 IF IsOpen(f.f) THEN BEGIN
@@ -260,18 +227,20 @@ BEGIN
260227 IF root = 0 THEN root := crec;
261228 IF prec <> 0 THEN BEGIN
262229 dbm_go(f, prec);
263- f.crec.next := crec;
264- f.needupdate := TRUE;
230+ WriteDWord(f.f, crec);
265231 END ;
266- prec := crec;
267- dbm_go(f, crec);
268232 csize := f.rblk_size;
269233 IF csize > size THEN csize := size;
270- Move(p^, f.data^, csize);
271- f.crec.size := csize;
272- f.needupdate := TRUE;
234+ dbm_go(f, crec);
235+ WriteDWord(f.f, 0 );
236+ WriteWord(f.f, csize);
237+ BlockWrite(f.f, p^, csize);
238+ IF f.rblk_size > csize THEN BEGIN
239+ FOR i := 1 TO f.rblk_size - csize DO WriteByte(f.f, 0 );
240+ END ;
273241 Dec(size, csize);
274242 Inc(p, csize);
243+ prec := crec;
275244 END ;
276245 END ;
277246 dbm_add := root;
@@ -282,12 +251,11 @@ VAR crec : LONGINT;
282251BEGIN
283252 IF NOT IsOpen(f.f) THEN EXIT;
284253 dbm_go(f, rec);
285- crec := f.crec.next;
286- f.crec.next := 0 ;
287- f.crec.size := 0 ;
288- f.needupdate := TRUE;
289- dbm_free(f, crec);
254+ crec := ReadDWord(f.f);
290255 dbm_go(f, rec);
256+ WriteDWord(f.f, 0 );
257+ WriteWord(f.f, 0 );
258+ dbm_free(f, crec);
291259 dbm_free(f, rec);
292260 dbm_add(f, b, size);
293261END ;
0 commit comments