@@ -288,90 +288,119 @@ static void devacuumHashTable(Yaz_file_struct* file) {
288288}
289289
290290static void refreshWindow (Yaz_file_struct* file) {
291- u32 copyLen;
292- u32 hh;
293- u32 uVar11;
294- int iVar7;
295- u16 res;
296- short sVar8 ;
297- u32 uVar16;
298- u32 uVar12;
299- u32 uVar3;
300-
301- copyLen = file->windowPos + 0x1 & 0xfff ;
302- hh = (u32 )file->window [copyLen + 0x1 & 0xfff ] << 0x8 |
303- (u32 )file->window [copyLen + 0x2 & 0xfff ] << 0x10 |
304- (u32 )file->window [copyLen];
305- uVar11 = hash1 (hh);
306- assert (uVar11 <= 0x3fff );
307- iVar7 = 0x4001 ;
308- res = file->hashMap [uVar11];
291+ // Calculate the next position in the circular window buffer
292+ u32 windowPos = file->windowPos + 1 & 0xfff ;
293+
294+ // Construct a 3-byte key from the window at the current position
295+ u32 key = (u32 )file->window [windowPos + 1 & 0xfff ] << 0x8 |
296+ (u32 )file->window [windowPos + 2 & 0xfff ] << 0x10 |
297+ (u32 )file->window [windowPos];
298+
299+ // Hash the key to find its bucket in the hash table
300+ u32 bucketIndex = hash1 (key);
301+ assert (bucketIndex <= 0x3fff );
302+
303+ // Linear probing to find the matching entry
304+ int probeLimit = 0x4001 ; // Prevent infinite loops
305+ u16 entry = file->hashMap [bucketIndex];
306+
307+ // Search for the entry that matches our window position
309308 while (true ) {
310- assert ((res & 0x8000 ) != 0 );
311- if (((res & 0x4000 ) != 0x0 ) && (copyLen == (res & 0x3fff ) ))
309+ assert (isEverUsed (entry) );
310+ if (isTombstone (entry) && windowPos == (entry & 0x3fff ))
312311 break ;
313- iVar7--;
314- assert (iVar7 != 0 );
315- uVar11 = uVar11 + 1 & 0x3fff ;
316- res = file->hashMap [uVar11];
312+
313+ probeLimit--;
314+ assert (probeLimit != 0 );
315+ bucketIndex = (bucketIndex + 1 ) & 0x3fff ;
316+ entry = file->hashMap [bucketIndex];
317317 }
318- sVar8 = 1 ;
319- iVar7 = 0x4 ;
320- uVar16 = copyLen;
318+
319+ // Check the next 4 positions to see if we have a matching sequence
320+ short offset = 1 ;
321+ int remainingChecks = 4 ;
322+ u32 checkPos = windowPos;
323+
321324 do {
322- uVar12 = uVar16 + 0x2 ;
323- uVar3 = uVar16 + 0x3 ;
324- uVar16++;
325- if (hh == ((u32 )file->window [uVar12 & 0xfff ] << 0x8 |
326- (u32 )file->window [uVar3 & 0xfff ] << 0x10 |
327- (u32 )file->window [uVar16 & 0xfff ])) {
328- file->hashMap [uVar11] = ((short )copyLen + sVar8 & 0xfffU ) | 0xc000 ;
325+ u32 pos2 = checkPos + 2 ;
326+ u32 pos3 = checkPos + 3 ;
327+ checkPos++;
328+
329+ // Construct key at the check position and compare with original key
330+ u32 checkKey = (u32 )file->window [pos2 & 0xfff ] << 0x8 |
331+ (u32 )file->window [pos3 & 0xfff ] << 0x10 |
332+ (u32 )file->window [checkPos & 0xfff ];
333+
334+ if (key == checkKey) {
335+ // Found a match, update the hash map entry with the new position and mark as tombstone
336+ file->hashMap [bucketIndex] = ((short )windowPos + offset & 0xfff ) | 0xc000 ;
329337 return ;
330338 }
331- sVar8 ++;
332- iVar7--;
333- } while (iVar7 != 0 );
339+
340+ offset++;
341+ remainingChecks--;
342+ } while (remainingChecks != 0 );
343+
344+ // No match found, mark the entry as a tombstone and increment vacancy counter
334345 file->hashVacancies ++;
335- file->hashMap [uVar11 ] = 0x8000 ;
346+ file->hashMap [bucketIndex ] = 0x8000 ;
336347}
337348
338349static void handleOtherTriple (Yaz_file_struct* file) {
339- u32 copyLen;
340- u32 uVar11;
341- int iVar7;
342- u32 uVar17;
343- u16 res;
350+ // Calculate the position in the window to copy from
351+ u32 windowPos = file->windowPos - 3 & 0xfff ;
352+
353+ // Construct the key from three consecutive bytes in the window
354+ u32 key = (u32 )file->window [(windowPos + 1 ) % WINDOW_SIZE] << 0x8 |
355+ (u32 )file->window [(windowPos + 2 ) % WINDOW_SIZE] << 0x10 |
356+ (u32 )file->window [windowPos];
357+
358+ // Check the next 4 positions to see if we have a matching key
359+ int remainingChecks = 4 ;
360+ u32 checkPos = windowPos;
344361
345- copyLen = file->windowPos - 3 & 0xfff ;
346- uVar11 = (u32 )file->window [(copyLen + 1 ) % WINDOW_SIZE] << 0x8 |
347- (u32 )file->window [(copyLen + 2 ) % WINDOW_SIZE] << 0x10 |
348- (u32 )file->window [copyLen];
349- iVar7 = 0x4 ;
350- uVar17 = copyLen;
351362 do {
352- if (uVar11 == ((u32 )file->window [uVar17 - 0x3 & 0xfff ] << 0x8 |
353- (u32 )file->window [uVar17 - 0x2 & 0xfff ] << 0x10 |
354- (u32 )file->window [uVar17 - 0x4 & 0xfff ]))
363+ // Construct key at the check position and compare with original key
364+ u32 checkKey = (u32 )file->window [checkPos - 0x3 & 0xfff ] << 0x8 |
365+ (u32 )file->window [checkPos - 0x2 & 0xfff ] << 0x10 |
366+ (u32 )file->window [checkPos - 0x4 & 0xfff ];
367+
368+ // If keys match, we're done
369+ if (key == checkKey)
355370 return ;
356- uVar17++;
357- iVar7--;
358- } while (iVar7 != 0x0 );
359- uVar17 = hash1 (uVar11);
360- assert (uVar17 < HASH_MAP_SIZE);
361- res = file->hashMap [uVar17];
362- if ((res & 0x4000 ) != 0x0 ) {
363- iVar7 = 0x4000 ;
371+
372+ checkPos++;
373+ remainingChecks--;
374+ } while (remainingChecks != 0 );
375+
376+ // Hash the key to find its bucket in the hash table
377+ u32 bucketIndex = hash1 (key);
378+ assert (bucketIndex < HASH_MAP_SIZE);
379+
380+ // Get the entry at the bucket
381+ u16 entry = file->hashMap [bucketIndex];
382+
383+ // Linear probing to find an available slot if needed
384+ if (isTombstone (entry)) {
385+ int probeLimit = 0x4000 ; // Prevent infinite loops
386+
364387 while (true ) {
365- uVar17 = uVar17 + 1 & 0x3fff ;
366- res = file->hashMap [uVar17];
367- if ((res & 0x4000 ) == 0x0 )
388+ bucketIndex = (bucketIndex + 1 ) & 0x3fff ;
389+ entry = file->hashMap [bucketIndex];
390+
391+ if (!isTombstone (entry))
368392 break ;
369- iVar7--;
370- assert (iVar7 != 0 );
393+
394+ probeLimit--;
395+ assert (probeLimit != 0 );
371396 }
372397 }
373- file->hashMap [uVar17] = (u16 )copyLen | 0xc000 ;
374- file->hashVacancies = file->hashVacancies - (res >> 0xf );
398+
399+ // Update the hash map with the new position and mark as used
400+ file->hashMap [bucketIndex] = (u16 )windowPos | 0xc000 ;
401+
402+ // Update vacancy counter if we're replacing a tombstone
403+ file->hashVacancies = file->hashVacancies - (entry >> 0xf );
375404}
376405
377406static std::optional<int > HandleNewInputByte (Yaz_file_struct* file, int value) {
0 commit comments