Skip to content

Commit 6f8aede

Browse files
committed
Rewrite part of commit 1bf3157 to preserve backward compatibility
1 parent 3135c12 commit 6f8aede

File tree

2 files changed

+38
-24
lines changed

2 files changed

+38
-24
lines changed

src/entropy/TPAQPredictor.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,25 @@ const int TPAQPredictor<true>::HASH_SIZE = 16 * 1024 * 1024;
2929
template<>
3030
const int TPAQPredictor<true>::HASH = 0x7FEB352D;
3131
template<>
32+
const int TPAQPredictor<true>::MASK_80808080 = 0x80808080;
33+
template<>
34+
const int TPAQPredictor<true>::MASK_F0F0F000 = 0xF0F0F000;
35+
template<>
36+
const int TPAQPredictor<true>::MASK_4F4FFFFF = 0x4F4FFFFF;
37+
template<>
3238
const int TPAQPredictor<false>::MAX_LENGTH = 88;
3339
template<>
3440
const int TPAQPredictor<false>::BUFFER_SIZE = 64 * 1024 * 1024;
3541
template<>
3642
const int TPAQPredictor<false>::HASH_SIZE = 16 * 1024 * 1024;
3743
template<>
3844
const int TPAQPredictor<false>::HASH = 0x7FEB352D;
45+
template<>
46+
const int TPAQPredictor<false>::MASK_80808080 = 0x80808080;
47+
template<>
48+
const int TPAQPredictor<false>::MASK_F0F0F000 = 0xF0F0F000;
49+
template<>
50+
const int TPAQPredictor<false>::MASK_4F4FFFFF = 0x4F4FFFFF;
3951

4052

4153
TPAQMixer::TPAQMixer()

src/entropy/TPAQPredictor.hpp

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2011-2025 Frederic Langlet
2+
Copyright 2011-2024 Frederic Langlet
33
Licensed under the Apache License, Version 2.0 (the "License");
44
you may not use this file except in compliance with the License.
55
you may obtain a copy of the License at
@@ -74,20 +74,22 @@ namespace kanzi
7474
static const int BUFFER_SIZE;
7575
static const int HASH_SIZE;
7676
static const int HASH;
77-
77+
static const int MASK_80808080;
78+
static const int MASK_F0F0F000;
79+
static const int MASK_4F4FFFFF;
7880

7981
#define SSE0_RATE(T) ((T == true) ? 6 : 7)
8082

8183
int _pr; // next predicted value (0-4095)
82-
uint _c0; // bitwise context: last 0-7 bits with a leading 1 (1-255)
83-
uint _c4; // last 4 whole bytes, last is in low 8 bits
84-
uint _c8; // last 8 to 4 whole bytes, last is in low 8 bits
84+
int _c0; // bitwise context: last 0-7 bits with a leading 1 (1-255)
85+
int _c4; // last 4 whole bytes, last is in low 8 bits
86+
int _c8; // last 8 to 4 whole bytes, last is in low 8 bits
8587
int _bpos; // number of bits in c0 (0-7)
8688
int _pos;
8789
int _binCount;
8890
int _matchLen;
8991
int _matchPos;
90-
uint _matchVal;
92+
int _matchVal;
9193
uint _hash;
9294
LogisticAdaptiveProbMap<false, SSE0_RATE(T)> _sse0;
9395
LogisticAdaptiveProbMap<false, 7> _sse1;
@@ -109,13 +111,13 @@ namespace kanzi
109111
uint8* _cp4;
110112
uint8* _cp5;
111113
uint8* _cp6;
112-
uint _ctx0; // contexts
113-
uint _ctx1;
114-
uint _ctx2;
115-
uint _ctx3;
116-
uint _ctx4;
117-
uint _ctx5;
118-
uint _ctx6;
114+
int _ctx0; // contexts
115+
int _ctx1;
116+
int _ctx2;
117+
int _ctx3;
118+
int _ctx4;
119+
int _ctx5;
120+
int _ctx6;
119121

120122
int hash(uint x, uint y) const;
121123

@@ -422,7 +424,7 @@ namespace kanzi
422424
_binCount += ((_c4 >> 7) & 1);
423425

424426
// Select Neural Net
425-
_mixer = &_mixers[(_c4 & _mixersMask) | ((_matchLen == 0) ? 0 : 1)];
427+
_mixer = &_mixers[(_matchLen != 0) ? (_c4 & _mixersMask) + 1 : _c4 & _mixersMask];
426428

427429
// Add contexts to NN
428430
_ctx0 = (_c4 & 0xFF) << 8;
@@ -433,11 +435,11 @@ namespace kanzi
433435
if (_binCount < (_pos >> 2)) {
434436
// Mostly text or mixed
435437
_ctx4 = createContext(_ctx1, _c4 ^ (_c8 & 0xFFFF));
436-
_ctx5 = (_c8 & 0xF0F0F000) | ((_c4 & 0xF0F0F000) >> 4);
438+
_ctx5 = (_c8 & MASK_F0F0F000) | ((_c4 & MASK_F0F0F000) >> 4);
437439

438440
if (T == true) {
439-
const uint h1 = ((_c4 & 0x80808080) == 0) ? _c4 & 0x4F4FFFFF : _c4 & 0x80808080;
440-
const uint h2 = ((_c8 & 0x80808080) == 0) ? _c8 & 0x4F4FFFFF : _c8 & 0x80808080;
441+
const int h1 = ((_c4 & MASK_80808080) == 0) ? _c4 & MASK_4F4FFFFF : _c4 & MASK_80808080;
442+
const int h2 = ((_c8 & MASK_80808080) == 0) ? _c8 & MASK_4F4FFFFF : _c8 & MASK_80808080;
441443
_ctx6 = hash(h1 << 2, h2 >> 2);
442444
}
443445
}
@@ -452,7 +454,7 @@ namespace kanzi
452454
}
453455

454456
findMatch();
455-
_matchVal = uint(_buffer[_matchPos & _bufferMask]) | 0x100;
457+
_matchVal = int(_buffer[_matchPos & _bufferMask]) | 0x100;
456458

457459
// Keep track current position
458460
_hashes[_hash] = _pos;
@@ -463,10 +465,10 @@ namespace kanzi
463465
// on SandyBridge/Windows and slower on SkyLake/Linux except when [ctx & 255 == 0]
464466
// (with c < 256). Hence, use XOR for _ctx5 which is the only context that fulfills
465467
// the condition.
466-
const int idx2 = (_ctx2 + _c0) & _statesMask;
467-
const int idx3 = (_ctx3 + _c0) & _statesMask;
468-
const int idx4 = (_ctx4 + _c0) & _statesMask;
469-
const int idx5 = (_ctx5 ^ _c0) & _statesMask;
468+
const int idx2 = (uint(_ctx2) + _c0) & _statesMask;
469+
const int idx3 = (uint(_ctx3) + _c0) & _statesMask;
470+
const int idx4 = (uint(_ctx4) + _c0) & _statesMask;
471+
const int idx5 = (uint(_ctx5) ^ _c0) & _statesMask;
470472
prefetchRead(&_bigStatesMap[idx2]);
471473
prefetchRead(&_bigStatesMap[idx3]);
472474
prefetchRead(&_bigStatesMap[idx4]);
@@ -505,7 +507,7 @@ namespace kanzi
505507
}
506508
} else {
507509
// One more prediction
508-
const int idx6 = (_ctx6 + _c0) & _statesMask;
510+
const int idx6 = (uint(_ctx6) + _c0) & _statesMask;
509511
prefetchRead(&_bigStatesMap[idx6]);
510512
*_cp6 = table[*_cp6];
511513
_cp6 = &_bigStatesMap[idx6];
@@ -565,7 +567,7 @@ namespace kanzi
565567
template <bool T>
566568
inline int TPAQPredictor<T>::hash(uint x, uint y) const
567569
{
568-
const uint h = x * HASH ^ y * HASH;
570+
const int h = x * HASH ^ y * HASH;
569571
return (h >> 1) ^ (h >> 9) ^ (x >> 2) ^ (y >> 3) ^ HASH;
570572
}
571573

0 commit comments

Comments
 (0)