Skip to content

Commit 8af2650

Browse files
committed
[szs] CTGP: More aggressive refactoring of refreshWindow and handleOtherTriple
1 parent 92bf6d5 commit 8af2650

File tree

1 file changed

+96
-67
lines changed

1 file changed

+96
-67
lines changed

source/szs/src/CTGP.cpp

Lines changed: 96 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -288,90 +288,119 @@ static void devacuumHashTable(Yaz_file_struct* file) {
288288
}
289289

290290
static 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

338349
static 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

377406
static std::optional<int> HandleNewInputByte(Yaz_file_struct* file, int value) {

0 commit comments

Comments
 (0)