Update fast-lzma2 to version 1.0.1

This commit is contained in:
Tino Reichardt
2019-07-29 08:58:39 +02:00
parent 2f4bcd7f4c
commit f8d5879212
12 changed files with 409 additions and 416 deletions

View File

@@ -55,7 +55,7 @@ Introduction
/*------ Version ------*/ /*------ Version ------*/
#define FL2_VERSION_MAJOR 1 #define FL2_VERSION_MAJOR 1
#define FL2_VERSION_MINOR 0 #define FL2_VERSION_MINOR 0
#define FL2_VERSION_RELEASE 0 #define FL2_VERSION_RELEASE 1
#define FL2_VERSION_NUMBER (FL2_VERSION_MAJOR *100*100 + FL2_VERSION_MINOR *100 + FL2_VERSION_RELEASE) #define FL2_VERSION_NUMBER (FL2_VERSION_MAJOR *100*100 + FL2_VERSION_MINOR *100 + FL2_VERSION_RELEASE)
FL2LIB_API unsigned FL2LIB_CALL FL2_versionNumber(void); /**< useful to check dll version */ FL2LIB_API unsigned FL2LIB_CALL FL2_versionNumber(void); /**< useful to check dll version */

View File

@@ -294,7 +294,7 @@ static size_t FL2_compressCurBlock_blocking(FL2_CCtx* const cctx, int const stre
cctx->jobs[nbThreads - 1].block.end = cctx->curBlock.end; cctx->jobs[nbThreads - 1].block.end = cctx->curBlock.end;
/* initialize to length 2 */ /* initialize to length 2 */
cctx->matchTable->progress = RMF_initTable(cctx->matchTable, cctx->curBlock.data, cctx->curBlock.end); RMF_initTable(cctx->matchTable, cctx->curBlock.data, cctx->curBlock.end);
if (cctx->canceled) { if (cctx->canceled) {
RMF_resetIncompleteBuild(cctx->matchTable); RMF_resetIncompleteBuild(cctx->matchTable);
@@ -666,7 +666,7 @@ FL2LIB_API size_t FL2LIB_CALL FL2_CCtx_setParameter(FL2_CCtx* cctx, FL2_cParamet
case FL2_p_dictionarySize: case FL2_p_dictionarySize:
CLAMPCHECK(value, FL2_DICTSIZE_MIN, FL2_DICTSIZE_MAX); CLAMPCHECK(value, FL2_DICTSIZE_MIN, FL2_DICTSIZE_MAX);
cctx->params.rParams.dictionary_size = value; cctx->params.rParams.dictionary_size = value;
break; break;
case FL2_p_overlapFraction: case FL2_p_overlapFraction:
MAXCHECK(value, FL2_BLOCK_OVERLAP_MAX); MAXCHECK(value, FL2_BLOCK_OVERLAP_MAX);
@@ -960,7 +960,7 @@ FL2LIB_API size_t FL2LIB_CALL FL2_copyCStreamOutput(FL2_CStream* fcs, FL2_outBuf
fcs->outPos = 0; fcs->outPos = 0;
} }
return 0; return 0;
} }
static size_t FL2_compressStream_input(FL2_CStream* fcs, FL2_inBuffer* input) static size_t FL2_compressStream_input(FL2_CStream* fcs, FL2_inBuffer* input)
@@ -1066,7 +1066,7 @@ FL2LIB_API size_t FL2LIB_CALL FL2_getNextCompressedBuffer(FL2_CStream* fcs, FL2_
cbuf->size = 0; cbuf->size = 0;
#ifndef FL2_SINGLETHREAD #ifndef FL2_SINGLETHREAD
CHECK_F(FL2_waitCStream(fcs)); CHECK_F(FL2_waitCStream(fcs));
#endif #endif
if (fcs->outThread < fcs->threadCount) { if (fcs->outThread < fcs->threadCount) {

View File

@@ -133,10 +133,10 @@ typedef struct
{ {
size_t table_size; size_t table_size;
unsigned prices[kNumPositionStatesMax][kLenNumSymbolsTotal]; unsigned prices[kNumPositionStatesMax][kLenNumSymbolsTotal];
Probability choice; /* low[0] is choice_2. Must be consecutive for speed */ LZMA2_prob choice; /* low[0] is choice_2. Must be consecutive for speed */
Probability low[kNumPositionStatesMax << (kLenNumLowBits + 1)]; LZMA2_prob low[kNumPositionStatesMax << (kLenNumLowBits + 1)];
Probability high[kLenNumHighSymbols]; LZMA2_prob high[kLenNumHighSymbols];
} LengthStates; } LZMA2_lenStates;
/* All probabilities for the encoder. This is a separate from the encoder object /* All probabilities for the encoder. This is a separate from the encoder object
* so the state can be saved and restored in case a chunk is not compressible. * so the state can be saved and restored in case a chunk is not compressible.
@@ -144,26 +144,26 @@ typedef struct
typedef struct typedef struct
{ {
/* Fields are ordered for speed */ /* Fields are ordered for speed */
LengthStates rep_len_states; LZMA2_lenStates rep_len_states;
Probability is_rep0_long[kNumStates][kNumPositionStatesMax]; LZMA2_prob is_rep0_long[kNumStates][kNumPositionStatesMax];
size_t state; size_t state;
U32 reps[kNumReps]; U32 reps[kNumReps];
Probability is_match[kNumStates][kNumPositionStatesMax]; LZMA2_prob is_match[kNumStates][kNumPositionStatesMax];
Probability is_rep[kNumStates]; LZMA2_prob is_rep[kNumStates];
Probability is_rep_G0[kNumStates]; LZMA2_prob is_rep_G0[kNumStates];
Probability is_rep_G1[kNumStates]; LZMA2_prob is_rep_G1[kNumStates];
Probability is_rep_G2[kNumStates]; LZMA2_prob is_rep_G2[kNumStates];
LengthStates len_states; LZMA2_lenStates len_states;
Probability dist_slot_encoders[kNumLenToPosStates][1 << kNumPosSlotBits]; LZMA2_prob dist_slot_encoders[kNumLenToPosStates][1 << kNumPosSlotBits];
Probability dist_align_encoders[1 << kNumAlignBits]; LZMA2_prob dist_align_encoders[1 << kNumAlignBits];
Probability dist_encoders[kNumFullDistances - kEndPosModelIndex]; LZMA2_prob dist_encoders[kNumFullDistances - kEndPosModelIndex];
Probability literal_probs[(kNumLiterals * kNumLitTables) << kLcLpMax]; LZMA2_prob literal_probs[(kNumLiterals * kNumLitTables) << kLcLpMax];
} EncoderStates; } LZMA2_encStates;
/* /*
* Linked list item for optimal parsing * Linked list item for optimal parsing
@@ -178,7 +178,7 @@ typedef struct
unsigned len; unsigned len;
U32 dist; U32 dist;
U32 reps[kNumReps]; U32 reps[kNumReps];
} OptimalNode; } LZMA2_node;
#define MARK_LITERAL(node) (node).dist = kNullDist; (node).extra = 0; #define MARK_LITERAL(node) (node).dist = kNullDist; (node).extra = 0;
#define MARK_SHORT_REP(node) (node).dist = 0; (node).extra = 0; #define MARK_SHORT_REP(node) (node).dist = 0; (node).extra = 0;
@@ -189,7 +189,7 @@ typedef struct
typedef struct { typedef struct {
S32 table_3[1 << kHash3Bits]; S32 table_3[1 << kHash3Bits];
S32 hash_chain_3[1]; S32 hash_chain_3[1];
} HashChains; } LZMA2_hc3;
/* /*
* LZMA2 encoder. * LZMA2 encoder.
@@ -206,13 +206,13 @@ struct LZMA2_ECtx_s
unsigned match_cycles; unsigned match_cycles;
FL2_strategy strategy; FL2_strategy strategy;
RangeEncoder rc; RC_encoder rc;
/* Finish writing the chunk at this size */ /* Finish writing the chunk at this size */
size_t chunk_size; size_t chunk_size;
/* Don't encode a symbol beyond this limit (used by fast mode) */ /* Don't encode a symbol beyond this limit (used by fast mode) */
size_t chunk_limit; size_t chunk_limit;
EncoderStates states; LZMA2_encStates states;
unsigned match_price_count; unsigned match_price_count;
unsigned rep_len_price_count; unsigned rep_len_price_count;
@@ -225,9 +225,9 @@ struct LZMA2_ECtx_s
RMF_match matches[kMatchesMax]; RMF_match matches[kMatchesMax];
size_t match_count; size_t match_count;
OptimalNode opt_buf[kOptimizerBufferSize]; LZMA2_node opt_buf[kOptimizerBufferSize];
HashChains* hash_buf; LZMA2_hc3* hash_buf;
ptrdiff_t chain_mask_2; ptrdiff_t chain_mask_2;
ptrdiff_t chain_mask_3; ptrdiff_t chain_mask_3;
ptrdiff_t hash_dict_3; ptrdiff_t hash_dict_3;
@@ -319,7 +319,7 @@ static unsigned LZMA_getRepMatch0Price(LZMA2_ECtx *const enc, size_t const len,
+ GET_PRICE_1(rep0_long_prob); + GET_PRICE_1(rep0_long_prob);
} }
static unsigned LZMA_getLiteralPriceMatched(const Probability *const prob_table, U32 symbol, unsigned match_byte) static unsigned LZMA_getLiteralPriceMatched(const LZMA2_prob *const prob_table, U32 symbol, unsigned match_byte)
{ {
unsigned price = 0; unsigned price = 0;
unsigned offs = 0x100; unsigned offs = 0x100;
@@ -334,12 +334,12 @@ static unsigned LZMA_getLiteralPriceMatched(const Probability *const prob_table,
} }
HINT_INLINE HINT_INLINE
void LZMA_encodeLiteral(LZMA2_ECtx *const enc, size_t const index, U32 symbol, unsigned const prev_symbol) void LZMA_encodeLiteral(LZMA2_ECtx *const enc, size_t const pos, U32 symbol, unsigned const prev_symbol)
{ {
RC_encodeBit0(&enc->rc, &enc->states.is_match[enc->states.state][index & enc->pos_mask]); RC_encodeBit0(&enc->rc, &enc->states.is_match[enc->states.state][pos & enc->pos_mask]);
enc->states.state = LIT_NEXT_STATE(enc->states.state); enc->states.state = LIT_NEXT_STATE(enc->states.state);
Probability* const prob_table = LITERAL_PROBS(enc, index, prev_symbol); LZMA2_prob* const prob_table = LITERAL_PROBS(enc, pos, prev_symbol);
symbol |= 0x100; symbol |= 0x100;
do { do {
RC_encodeBit(&enc->rc, prob_table + (symbol >> 8), symbol & (1 << 7)); RC_encodeBit(&enc->rc, prob_table + (symbol >> 8), symbol & (1 << 7));
@@ -348,13 +348,13 @@ void LZMA_encodeLiteral(LZMA2_ECtx *const enc, size_t const index, U32 symbol, u
} }
HINT_INLINE HINT_INLINE
void LZMA_encodeLiteralMatched(LZMA2_ECtx *const enc, const BYTE* const data_block, size_t const index, U32 symbol) void LZMA_encodeLiteralMatched(LZMA2_ECtx *const enc, const BYTE* const data_block, size_t const pos, U32 symbol)
{ {
RC_encodeBit0(&enc->rc, &enc->states.is_match[enc->states.state][index & enc->pos_mask]); RC_encodeBit0(&enc->rc, &enc->states.is_match[enc->states.state][pos & enc->pos_mask]);
enc->states.state = LIT_NEXT_STATE(enc->states.state); enc->states.state = LIT_NEXT_STATE(enc->states.state);
unsigned match_symbol = data_block[index - enc->states.reps[0] - 1]; unsigned match_symbol = data_block[pos - enc->states.reps[0] - 1];
Probability* const prob_table = LITERAL_PROBS(enc, index, data_block[index - 1]); LZMA2_prob* const prob_table = LITERAL_PROBS(enc, pos, data_block[pos - 1]);
unsigned offset = 0x100; unsigned offset = 0x100;
symbol |= 0x100; symbol |= 0x100;
do { do {
@@ -367,19 +367,19 @@ void LZMA_encodeLiteralMatched(LZMA2_ECtx *const enc, const BYTE* const data_blo
} }
HINT_INLINE HINT_INLINE
void LZMA_encodeLiteralBuf(LZMA2_ECtx *const enc, const BYTE* const data_block, size_t const index) void LZMA_encodeLiteralBuf(LZMA2_ECtx *const enc, const BYTE* const data_block, size_t const pos)
{ {
U32 const symbol = data_block[index]; U32 const symbol = data_block[pos];
if (IS_LIT_STATE(enc->states.state)) { if (IS_LIT_STATE(enc->states.state)) {
unsigned const prev_symbol = data_block[index - 1]; unsigned const prev_symbol = data_block[pos - 1];
LZMA_encodeLiteral(enc, index, symbol, prev_symbol); LZMA_encodeLiteral(enc, pos, symbol, prev_symbol);
} }
else { else {
LZMA_encodeLiteralMatched(enc, data_block, index, symbol); LZMA_encodeLiteralMatched(enc, data_block, pos, symbol);
} }
} }
static void LZMA_lengthStates_SetPrices(const Probability *probs, U32 start_price, unsigned *prices) static void LZMA_lengthStates_SetPrices(const LZMA2_prob *probs, U32 start_price, unsigned *prices)
{ {
for (size_t i = 0; i < 8; i += 2) { for (size_t i = 0; i < 8; i += 2) {
U32 prob = probs[4 + (i >> 1)]; U32 prob = probs[4 + (i >> 1)];
@@ -391,7 +391,7 @@ static void LZMA_lengthStates_SetPrices(const Probability *probs, U32 start_pric
} }
FORCE_NOINLINE FORCE_NOINLINE
static void LZMA_lengthStates_updatePrices(LZMA2_ECtx *const enc, LengthStates* const ls) static void LZMA_lengthStates_updatePrices(LZMA2_ECtx *const enc, LZMA2_lenStates* const ls)
{ {
U32 b; U32 b;
@@ -403,7 +403,7 @@ static void LZMA_lengthStates_updatePrices(LZMA2_ECtx *const enc, LengthStates*
c = b + GET_PRICE_0(ls->low[0]); c = b + GET_PRICE_0(ls->low[0]);
for (size_t pos_state = 0; pos_state <= enc->pos_mask; pos_state++) { for (size_t pos_state = 0; pos_state <= enc->pos_mask; pos_state++) {
unsigned *const prices = ls->prices[pos_state]; unsigned *const prices = ls->prices[pos_state];
const Probability *const probs = ls->low + (pos_state << (1 + kLenNumLowBits)); const LZMA2_prob *const probs = ls->low + (pos_state << (1 + kLenNumLowBits));
LZMA_lengthStates_SetPrices(probs, a, prices); LZMA_lengthStates_SetPrices(probs, a, prices);
LZMA_lengthStates_SetPrices(probs + kLenNumLowSymbols, c, prices + kLenNumLowSymbols); LZMA_lengthStates_SetPrices(probs + kLenNumLowSymbols, c, prices + kLenNumLowSymbols);
} }
@@ -412,7 +412,7 @@ static void LZMA_lengthStates_updatePrices(LZMA2_ECtx *const enc, LengthStates*
size_t i = ls->table_size; size_t i = ls->table_size;
if (i > kLenNumLowSymbols * 2) { if (i > kLenNumLowSymbols * 2) {
const Probability *const probs = ls->high; const LZMA2_prob *const probs = ls->high;
unsigned *const prices = ls->prices[0] + kLenNumLowSymbols * 2; unsigned *const prices = ls->prices[0] + kLenNumLowSymbols * 2;
i = (i - (kLenNumLowSymbols * 2 - 1)) >> 1; i = (i - (kLenNumLowSymbols * 2 - 1)) >> 1;
b += GET_PRICE_1(ls->low[0]); b += GET_PRICE_1(ls->low[0]);
@@ -439,7 +439,7 @@ static void LZMA_lengthStates_updatePrices(LZMA2_ECtx *const enc, LengthStates*
/* Rare enough that not inlining is faster overall */ /* Rare enough that not inlining is faster overall */
FORCE_NOINLINE FORCE_NOINLINE
static void LZMA_encodeLength_MidHigh(LZMA2_ECtx *const enc, LengthStates* const len_prob_table, unsigned const len, size_t const pos_state) static void LZMA_encodeLength_MidHigh(LZMA2_ECtx *const enc, LZMA2_lenStates* const len_prob_table, unsigned const len, size_t const pos_state)
{ {
RC_encodeBit1(&enc->rc, &len_prob_table->choice); RC_encodeBit1(&enc->rc, &len_prob_table->choice);
if (len < kLenNumLowSymbols * 2) { if (len < kLenNumLowSymbols * 2) {
@@ -453,7 +453,7 @@ static void LZMA_encodeLength_MidHigh(LZMA2_ECtx *const enc, LengthStates* const
} }
HINT_INLINE HINT_INLINE
void LZMA_encodeLength(LZMA2_ECtx *const enc, LengthStates* const len_prob_table, unsigned len, size_t const pos_state) void LZMA_encodeLength(LZMA2_ECtx *const enc, LZMA2_lenStates* const len_prob_table, unsigned len, size_t const pos_state)
{ {
len -= kMatchLenMin; len -= kMatchLenMin;
if (len < kLenNumLowSymbols) { if (len < kLenNumLowSymbols) {
@@ -580,22 +580,22 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
FL2_dataBlock const block, FL2_dataBlock const block,
FL2_matchTable* const tbl, FL2_matchTable* const tbl,
int const struct_tbl, int const struct_tbl,
size_t index, size_t pos,
size_t const uncompressed_end) size_t const uncompressed_end)
{ {
size_t const pos_mask = enc->pos_mask; size_t const pos_mask = enc->pos_mask;
size_t prev = index; size_t prev = pos;
unsigned const search_depth = tbl->params.depth; unsigned const search_depth = tbl->params.depth;
while (index < uncompressed_end && enc->rc.out_index < enc->chunk_size) { while (pos < uncompressed_end && enc->rc.out_index < enc->chunk_size) {
size_t max_len; size_t max_len;
const BYTE* data; const BYTE* data;
/* Table of distance restrictions for short matches */ /* Table of distance restrictions for short matches */
static const U32 max_dist_table[] = { 0, 0, 0, 1 << 6, 1 << 14 }; static const U32 max_dist_table[] = { 0, 0, 0, 1 << 6, 1 << 14 };
/* Get a match from the table, extended to its full length */ /* Get a match from the table, extended to its full length */
RMF_match best_match = RMF_getMatch(block, tbl, search_depth, struct_tbl, index); RMF_match best_match = RMF_getMatch(block, tbl, search_depth, struct_tbl, pos);
if (best_match.length < kMatchLenMin) { if (best_match.length < kMatchLenMin) {
++index; ++pos;
continue; continue;
} }
/* Use if near enough */ /* Use if near enough */
@@ -604,8 +604,8 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
else else
best_match.length = 0; best_match.length = 0;
max_len = MIN(kMatchLenMax, block.end - index); max_len = MIN(kMatchLenMax, block.end - pos);
data = block.data + index; data = block.data + pos;
RMF_match best_rep = { 0, 0 }; RMF_match best_rep = { 0, 0 };
RMF_match rep_match; RMF_match rep_match;
@@ -643,11 +643,11 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
} }
if (best_match.length < kMatchLenMin) { if (best_match.length < kMatchLenMin) {
++index; ++pos;
continue; continue;
} }
for (size_t next = index + 1; best_match.length < kMatchLenMax && next < uncompressed_end; ++next) { for (size_t next = pos + 1; best_match.length < kMatchLenMax && next < uncompressed_end; ++next) {
/* lazy matching scheme from ZSTD */ /* lazy matching scheme from ZSTD */
RMF_match next_match = RMF_getNextMatch(block, tbl, search_depth, struct_tbl, next); RMF_match next_match = RMF_getNextMatch(block, tbl, search_depth, struct_tbl, next);
if (next_match.length >= kMatchLenMin) { if (next_match.length >= kMatchLenMin) {
@@ -669,7 +669,7 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
if (gain2 > gain1) { if (gain2 > gain1) {
DEBUGLOG(7, "Replace match (%u, %u) with rep (%u, %u)", best_match.length, best_match.dist, best_rep.length, best_rep.dist); DEBUGLOG(7, "Replace match (%u, %u) with rep (%u, %u)", best_match.length, best_match.dist, best_rep.length, best_rep.dist);
best_match = best_rep; best_match = best_rep;
index = next; pos = next;
} }
} }
if (next_match.length >= 3 && next_match.dist != best_match.dist) { if (next_match.length >= 3 && next_match.dist != best_match.dist) {
@@ -679,7 +679,7 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
DEBUGLOG(7, "Replace match (%u, %u) with match (%u, %u)", best_match.length, best_match.dist, next_match.length, next_match.dist + kNumReps); DEBUGLOG(7, "Replace match (%u, %u) with match (%u, %u)", best_match.length, best_match.dist, next_match.length, next_match.dist + kNumReps);
best_match = next_match; best_match = next_match;
best_match.dist += kNumReps; best_match.dist += kNumReps;
index = next; pos = next;
continue; continue;
} }
} }
@@ -712,7 +712,7 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
if (gain2 > gain1) { if (gain2 > gain1) {
DEBUGLOG(7, "Replace match (%u, %u) with rep (%u, %u)", best_match.length, best_match.dist, best_rep.length, best_rep.dist); DEBUGLOG(7, "Replace match (%u, %u) with rep (%u, %u)", best_match.length, best_match.dist, best_rep.length, best_rep.dist);
best_match = best_rep; best_match = best_rep;
index = next; pos = next;
} }
} }
if (next_match.dist != best_match.dist) { if (next_match.dist != best_match.dist) {
@@ -722,7 +722,7 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
DEBUGLOG(7, "Replace match (%u, %u) with match (%u, %u)", best_match.length, best_match.dist, next_match.length, next_match.dist + kNumReps); DEBUGLOG(7, "Replace match (%u, %u) with match (%u, %u)", best_match.length, best_match.dist, next_match.length, next_match.dist + kNumReps);
best_match = next_match; best_match = next_match;
best_match.dist += kNumReps; best_match.dist += kNumReps;
index = next; pos = next;
continue; continue;
} }
} }
@@ -730,9 +730,9 @@ size_t LZMA_encodeChunkFast(LZMA2_ECtx *const enc,
break; break;
} }
_encode: _encode:
assert(index + best_match.length <= block.end); assert(pos + best_match.length <= block.end);
while (prev < index) { while (prev < pos) {
if (enc->rc.out_index >= enc->chunk_limit) if (enc->rc.out_index >= enc->chunk_limit)
return prev; return prev;
@@ -748,18 +748,18 @@ _encode:
if(best_match.length >= kMatchLenMin) { if(best_match.length >= kMatchLenMin) {
if (best_match.dist >= kNumReps) { if (best_match.dist >= kNumReps) {
LZMA_encodeNormalMatch(enc, best_match.length, best_match.dist - kNumReps, index & pos_mask); LZMA_encodeNormalMatch(enc, best_match.length, best_match.dist - kNumReps, pos & pos_mask);
index += best_match.length; pos += best_match.length;
prev = index; prev = pos;
} }
else { else {
LZMA_encodeRepMatchLong(enc, best_match.length, best_match.dist, index & pos_mask); LZMA_encodeRepMatchLong(enc, best_match.length, best_match.dist, pos & pos_mask);
index += best_match.length; pos += best_match.length;
prev = index; prev = pos;
} }
} }
} }
while (prev < index && enc->rc.out_index < enc->chunk_limit) { while (prev < pos && enc->rc.out_index < enc->chunk_limit) {
if (block.data[prev] != block.data[prev - enc->states.reps[0] - 1]) if (block.data[prev] != block.data[prev - enc->states.reps[0] - 1])
LZMA_encodeLiteralBuf(enc, block.data, prev); LZMA_encodeLiteralBuf(enc, block.data, prev);
else else
@@ -773,7 +773,7 @@ _encode:
* Reverse the direction of the linked list generated by the optimal parser * Reverse the direction of the linked list generated by the optimal parser
*/ */
FORCE_NOINLINE FORCE_NOINLINE
static void LZMA_reverseOptimalChain(OptimalNode* const opt_buf, size_t cur) static void LZMA_reverseOptimalChain(LZMA2_node* const opt_buf, size_t cur)
{ {
unsigned len = (unsigned)opt_buf[cur].len; unsigned len = (unsigned)opt_buf[cur].len;
U32 dist = opt_buf[cur].dist; U32 dist = opt_buf[cur].dist;
@@ -814,9 +814,9 @@ static void LZMA_reverseOptimalChain(OptimalNode* const opt_buf, size_t cur)
} }
} }
static unsigned LZMA_getLiteralPrice(LZMA2_ECtx *const enc, size_t const index, size_t const state, unsigned const prev_symbol, U32 symbol, unsigned const match_byte) static unsigned LZMA_getLiteralPrice(LZMA2_ECtx *const enc, size_t const pos, size_t const state, unsigned const prev_symbol, U32 symbol, unsigned const match_byte)
{ {
const Probability* const prob_table = LITERAL_PROBS(enc, index, prev_symbol); const LZMA2_prob* const prob_table = LITERAL_PROBS(enc, pos, prev_symbol);
if (IS_LIT_STATE(state)) { if (IS_LIT_STATE(state)) {
unsigned price = 0; unsigned price = 0;
symbol |= 0x100; symbol |= 0x100;
@@ -850,7 +850,7 @@ static int LZMA_hashCreate(LZMA2_ECtx *const enc, unsigned const dictionary_bits
free(enc->hash_buf); free(enc->hash_buf);
enc->hash_alloc_3 = (ptrdiff_t)1 << dictionary_bits_3; enc->hash_alloc_3 = (ptrdiff_t)1 << dictionary_bits_3;
enc->hash_buf = malloc(sizeof(HashChains) + (enc->hash_alloc_3 - 1) * sizeof(S32)); enc->hash_buf = malloc(sizeof(LZMA2_hc3) + (enc->hash_alloc_3 - 1) * sizeof(S32));
if (enc->hash_buf == NULL) if (enc->hash_buf == NULL)
return 1; return 1;
@@ -879,34 +879,34 @@ int LZMA2_hashAlloc(LZMA2_ECtx *const enc, const FL2_lzma2Parameters* const opti
*/ */
HINT_INLINE HINT_INLINE
size_t LZMA_hashGetMatches(LZMA2_ECtx *const enc, FL2_dataBlock const block, size_t LZMA_hashGetMatches(LZMA2_ECtx *const enc, FL2_dataBlock const block,
ptrdiff_t const index, ptrdiff_t const pos,
size_t const length_limit, size_t const length_limit,
RMF_match const match) RMF_match const match)
{ {
ptrdiff_t const hash_dict_3 = enc->hash_dict_3; ptrdiff_t const hash_dict_3 = enc->hash_dict_3;
const BYTE* data = block.data; const BYTE* data = block.data;
HashChains* const tbl = enc->hash_buf; LZMA2_hc3* const tbl = enc->hash_buf;
ptrdiff_t const chain_mask_3 = enc->chain_mask_3; ptrdiff_t const chain_mask_3 = enc->chain_mask_3;
enc->match_count = 0; enc->match_count = 0;
enc->hash_prev_index = MAX(enc->hash_prev_index, index - hash_dict_3); enc->hash_prev_index = MAX(enc->hash_prev_index, pos - hash_dict_3);
/* Update hash tables and chains for any positions that were skipped */ /* Update hash tables and chains for any positions that were skipped */
while (++enc->hash_prev_index < index) { while (++enc->hash_prev_index < pos) {
size_t hash = GET_HASH_3(data + enc->hash_prev_index); size_t hash = GET_HASH_3(data + enc->hash_prev_index);
tbl->hash_chain_3[enc->hash_prev_index & chain_mask_3] = tbl->table_3[hash]; tbl->hash_chain_3[enc->hash_prev_index & chain_mask_3] = tbl->table_3[hash];
tbl->table_3[hash] = (S32)enc->hash_prev_index; tbl->table_3[hash] = (S32)enc->hash_prev_index;
} }
data += index; data += pos;
size_t const hash = GET_HASH_3(data); size_t const hash = GET_HASH_3(data);
ptrdiff_t const first_3 = tbl->table_3[hash]; ptrdiff_t const first_3 = tbl->table_3[hash];
tbl->table_3[hash] = (S32)index; tbl->table_3[hash] = (S32)pos;
size_t max_len = 2; size_t max_len = 2;
if (first_3 >= 0) { if (first_3 >= 0) {
int cycles = enc->match_cycles; int cycles = enc->match_cycles;
ptrdiff_t const end_index = index - (((ptrdiff_t)match.dist < hash_dict_3) ? match.dist : hash_dict_3); ptrdiff_t const end_index = pos - (((ptrdiff_t)match.dist < hash_dict_3) ? match.dist : hash_dict_3);
ptrdiff_t match_3 = first_3; ptrdiff_t match_3 = first_3;
if (match_3 >= end_index) { if (match_3 >= end_index) {
do { do {
@@ -915,7 +915,7 @@ size_t LZMA_hashGetMatches(LZMA2_ECtx *const enc, FL2_dataBlock const block,
size_t len_test = ZSTD_count(data + 1, data_2 + 1, data + length_limit) + 1; size_t len_test = ZSTD_count(data + 1, data_2 + 1, data + length_limit) + 1;
if (len_test > max_len) { if (len_test > max_len) {
enc->matches[enc->match_count].length = (U32)len_test; enc->matches[enc->match_count].length = (U32)len_test;
enc->matches[enc->match_count].dist = (U32)(index - match_3 - 1); enc->matches[enc->match_count].dist = (U32)(pos - match_3 - 1);
++enc->match_count; ++enc->match_count;
max_len = len_test; max_len = len_test;
if (len_test >= length_limit) if (len_test >= length_limit)
@@ -927,7 +927,7 @@ size_t LZMA_hashGetMatches(LZMA2_ECtx *const enc, FL2_dataBlock const block,
} while (match_3 >= end_index); } while (match_3 >= end_index);
} }
} }
tbl->hash_chain_3[index & chain_mask_3] = (S32)first_3; tbl->hash_chain_3[pos & chain_mask_3] = (S32)first_3;
if ((unsigned)max_len < match.length) { if ((unsigned)max_len < match.length) {
/* Insert the match from the RMF */ /* Insert the match from the RMF */
enc->matches[enc->match_count] = match; enc->matches[enc->match_count] = match;
@@ -948,16 +948,16 @@ size_t LZMA_hashGetMatches(LZMA2_ECtx *const enc, FL2_dataBlock const block,
FORCE_INLINE_TEMPLATE FORCE_INLINE_TEMPLATE
size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block, size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
RMF_match match, RMF_match match,
size_t const index, size_t const pos,
size_t const cur, size_t const cur,
size_t len_end, size_t len_end,
int const is_hybrid, int const is_hybrid,
U32* const reps) U32* const reps)
{ {
OptimalNode* const cur_opt = &enc->opt_buf[cur]; LZMA2_node* const cur_opt = &enc->opt_buf[cur];
size_t const pos_mask = enc->pos_mask; size_t const pos_mask = enc->pos_mask;
size_t const pos_state = (index & pos_mask); size_t const pos_state = (pos & pos_mask);
const BYTE* const data = block.data + index; const BYTE* const data = block.data + pos;
size_t const fast_length = enc->fast_length; size_t const fast_length = enc->fast_length;
size_t prev_index = cur - cur_opt->len; size_t prev_index = cur - cur_opt->len;
size_t state; size_t state;
@@ -983,7 +983,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
state = enc->opt_buf[prev_index].state; state = enc->opt_buf[prev_index].state;
state = MATCH_NEXT_STATE(state) + (dist < kNumReps); state = MATCH_NEXT_STATE(state) + (dist < kNumReps);
} }
const OptimalNode *const prev_opt = &enc->opt_buf[prev_index]; const LZMA2_node *const prev_opt = &enc->opt_buf[prev_index];
if (dist < kNumReps) { if (dist < kNumReps) {
/* Move the chosen rep to the front. /* Move the chosen rep to the front.
* The table is hideous but faster than branching :D */ * The table is hideous but faster than branching :D */
@@ -1008,12 +1008,12 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
} }
cur_opt->state = state; cur_opt->state = state;
memcpy(cur_opt->reps, reps, sizeof(cur_opt->reps)); memcpy(cur_opt->reps, reps, sizeof(cur_opt->reps));
Probability const is_rep_prob = enc->states.is_rep[state]; LZMA2_prob const is_rep_prob = enc->states.is_rep[state];
{ OptimalNode *const next_opt = &enc->opt_buf[cur + 1]; { LZMA2_node *const next_opt = &enc->opt_buf[cur + 1];
U32 const cur_price = cur_opt->price; U32 const cur_price = cur_opt->price;
U32 const next_price = next_opt->price; U32 const next_price = next_opt->price;
Probability const is_match_prob = enc->states.is_match[state][pos_state]; LZMA2_prob const is_match_prob = enc->states.is_match[state][pos_state];
unsigned const cur_byte = *data; unsigned const cur_byte = *data;
unsigned const match_byte = *(data - reps[0] - 1); unsigned const match_byte = *(data - reps[0] - 1);
@@ -1022,7 +1022,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
BYTE try_lit = cur_and_lit_price + kMinLitPrice / 2U <= next_price; BYTE try_lit = cur_and_lit_price + kMinLitPrice / 2U <= next_price;
if (try_lit) { if (try_lit) {
/* cur_and_lit_price is used later for the literal + rep0 test */ /* cur_and_lit_price is used later for the literal + rep0 test */
cur_and_lit_price += LZMA_getLiteralPrice(enc, index, state, data[-1], cur_byte, match_byte); cur_and_lit_price += LZMA_getLiteralPrice(enc, pos, state, data[-1], cur_byte, match_byte);
/* Try literal */ /* Try literal */
if (cur_and_lit_price < next_price) { if (cur_and_lit_price < next_price) {
next_opt->price = cur_and_lit_price; next_opt->price = cur_and_lit_price;
@@ -1043,7 +1043,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
MARK_SHORT_REP(*next_opt); MARK_SHORT_REP(*next_opt);
} }
} }
bytes_avail = MIN(block.end - index, kOptimizerBufferSize - 1 - cur); bytes_avail = MIN(block.end - pos, kOptimizerBufferSize - 1 - cur);
if (bytes_avail < 2) if (bytes_avail < 2)
return len_end; return len_end;
@@ -1055,7 +1055,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
size_t len_test_2 = ZSTD_count(data + 1, data_2, data + 1 + limit); size_t len_test_2 = ZSTD_count(data + 1, data_2, data + 1 + limit);
if (len_test_2 >= 2) { if (len_test_2 >= 2) {
size_t const state_2 = LIT_NEXT_STATE(state); size_t const state_2 = LIT_NEXT_STATE(state);
size_t const pos_state_next = (index + 1) & pos_mask; size_t const pos_state_next = (pos + 1) & pos_mask;
U32 const next_rep_match_price = cur_and_lit_price + U32 const next_rep_match_price = cur_and_lit_price +
GET_PRICE_1(enc->states.is_match[state_2][pos_state_next]) + GET_PRICE_1(enc->states.is_match[state_2][pos_state_next]) +
GET_PRICE_1(enc->states.is_rep[state_2]); GET_PRICE_1(enc->states.is_rep[state_2]);
@@ -1092,7 +1092,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
/* Try rep match */ /* Try rep match */
do { do {
U32 const cur_and_len_price = cur_rep_price + enc->states.rep_len_states.prices[pos_state][len - kMatchLenMin]; U32 const cur_and_len_price = cur_rep_price + enc->states.rep_len_states.prices[pos_state][len - kMatchLenMin];
OptimalNode *const opt = &enc->opt_buf[cur + len]; LZMA2_node *const opt = &enc->opt_buf[cur + len];
if (cur_and_len_price < opt->price) { if (cur_and_len_price < opt->price) {
opt->price = cur_and_len_price; opt->price = cur_and_len_price;
opt->len = (unsigned)len; opt->len = (unsigned)len;
@@ -1114,15 +1114,15 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
data_2 + len_test + 3, data_2 + len_test + 3,
data + MIN(len_test + 1 + fast_length, bytes_avail)) + 2; data + MIN(len_test + 1 + fast_length, bytes_avail)) + 2;
size_t state_2 = REP_NEXT_STATE(state); size_t state_2 = REP_NEXT_STATE(state);
size_t pos_state_next = (index + len_test) & pos_mask; size_t pos_state_next = (pos + len_test) & pos_mask;
U32 rep_lit_rep_total_price = U32 rep_lit_rep_total_price =
cur_rep_price + enc->states.rep_len_states.prices[pos_state][len_test - kMatchLenMin] cur_rep_price + enc->states.rep_len_states.prices[pos_state][len_test - kMatchLenMin]
+ GET_PRICE_0(enc->states.is_match[state_2][pos_state_next]) + GET_PRICE_0(enc->states.is_match[state_2][pos_state_next])
+ LZMA_getLiteralPriceMatched(LITERAL_PROBS(enc, index + len_test, data[len_test - 1]), + LZMA_getLiteralPriceMatched(LITERAL_PROBS(enc, pos + len_test, data[len_test - 1]),
data[len_test], data_2[len_test]); data[len_test], data_2[len_test]);
state_2 = kState_LitAfterRep; state_2 = kState_LitAfterRep;
pos_state_next = (index + len_test + 1) & pos_mask; pos_state_next = (pos + len_test + 1) & pos_mask;
rep_lit_rep_total_price += rep_lit_rep_total_price +=
GET_PRICE_1(enc->states.is_match[state_2][pos_state_next]) + GET_PRICE_1(enc->states.is_match[state_2][pos_state_next]) +
GET_PRICE_1(enc->states.is_rep[state_2]); GET_PRICE_1(enc->states.is_rep[state_2]);
@@ -1157,7 +1157,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
else else
cur_and_len_price += enc->dist_slot_prices[len_to_dist_state][dist_slot] + enc->align_prices[cur_dist & kAlignMask]; cur_and_len_price += enc->dist_slot_prices[len_to_dist_state][dist_slot] + enc->align_prices[cur_dist & kAlignMask];
OptimalNode *const opt = &enc->opt_buf[cur + len_test]; LZMA2_node *const opt = &enc->opt_buf[cur + len_test];
if (cur_and_len_price < opt->price) { if (cur_and_len_price < opt->price) {
opt->price = cur_and_len_price; opt->price = cur_and_len_price;
opt->len = (unsigned)len_test; opt->len = (unsigned)len_test;
@@ -1179,7 +1179,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
main_len = match.length; main_len = match.length;
} }
else { else {
main_len = LZMA_hashGetMatches(enc, block, index, max_length, match); main_len = LZMA_hashGetMatches(enc, block, pos, max_length, match);
} }
ptrdiff_t match_index = enc->match_count - 1; ptrdiff_t match_index = enc->match_count - 1;
len_end = MAX(len_end, cur + main_len); len_end = MAX(len_end, cur + main_len);
@@ -1210,7 +1210,7 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
BYTE const sub_len = len_test < enc->matches[match_index].length; BYTE const sub_len = len_test < enc->matches[match_index].length;
OptimalNode *const opt = &enc->opt_buf[cur + len_test]; LZMA2_node *const opt = &enc->opt_buf[cur + len_test];
if (cur_and_len_price < opt->price) { if (cur_and_len_price < opt->price) {
opt->price = cur_and_len_price; opt->price = cur_and_len_price;
opt->len = (unsigned)len_test; opt->len = (unsigned)len_test;
@@ -1225,10 +1225,10 @@ size_t LZMA_optimalParse(LZMA2_ECtx* const enc, FL2_dataBlock const block,
size_t const limit = MIN(rep_0_pos + fast_length, bytes_avail); size_t const limit = MIN(rep_0_pos + fast_length, bytes_avail);
size_t const len_test_2 = ZSTD_count(data + rep_0_pos + 2, data_2 + rep_0_pos + 2, data + limit) + 2; size_t const len_test_2 = ZSTD_count(data + rep_0_pos + 2, data_2 + rep_0_pos + 2, data + limit) + 2;
size_t state_2 = MATCH_NEXT_STATE(state); size_t state_2 = MATCH_NEXT_STATE(state);
size_t pos_state_next = (index + len_test) & pos_mask; size_t pos_state_next = (pos + len_test) & pos_mask;
U32 match_lit_rep_total_price = cur_and_len_price + U32 match_lit_rep_total_price = cur_and_len_price +
GET_PRICE_0(enc->states.is_match[state_2][pos_state_next]) + GET_PRICE_0(enc->states.is_match[state_2][pos_state_next]) +
LZMA_getLiteralPriceMatched(LITERAL_PROBS(enc, index + len_test, data[len_test - 1]), LZMA_getLiteralPriceMatched(LITERAL_PROBS(enc, pos + len_test, data[len_test - 1]),
data[len_test], data_2[len_test]); data[len_test], data_2[len_test]);
state_2 = kState_LitAfterMatch; state_2 = kState_LitAfterMatch;
@@ -1287,19 +1287,19 @@ static void LZMA_initMatchesPos0(LZMA2_ECtx *const enc,
FORCE_NOINLINE FORCE_NOINLINE
static size_t LZMA_initMatchesPos0Best(LZMA2_ECtx *const enc, FL2_dataBlock const block, static size_t LZMA_initMatchesPos0Best(LZMA2_ECtx *const enc, FL2_dataBlock const block,
RMF_match const match, RMF_match const match,
size_t const index, size_t const pos,
size_t start_len, size_t start_len,
unsigned const normal_match_price) unsigned const normal_match_price)
{ {
if (start_len <= match.length) { if (start_len <= match.length) {
size_t main_len; size_t main_len;
if (match.length < 3 || block.end - index < 4) { if (match.length < 3 || block.end - pos < 4) {
enc->matches[0] = match; enc->matches[0] = match;
enc->match_count = 1; enc->match_count = 1;
main_len = match.length; main_len = match.length;
} }
else { else {
main_len = LZMA_hashGetMatches(enc, block, index, MIN(block.end - index, enc->fast_length), match); main_len = LZMA_hashGetMatches(enc, block, pos, MIN(block.end - pos, enc->fast_length), match);
} }
ptrdiff_t start_match = 0; ptrdiff_t start_match = 0;
@@ -1308,7 +1308,7 @@ static size_t LZMA_initMatchesPos0Best(LZMA2_ECtx *const enc, FL2_dataBlock cons
enc->matches[start_match - 1].length = (U32)start_len - 1; /* Avoids an if..else branch in the loop. [-1] is ok */ enc->matches[start_match - 1].length = (U32)start_len - 1; /* Avoids an if..else branch in the loop. [-1] is ok */
size_t pos_state = index & enc->pos_mask; size_t pos_state = pos & enc->pos_mask;
for (ptrdiff_t match_index = enc->match_count - 1; match_index >= start_match; --match_index) { for (ptrdiff_t match_index = enc->match_count - 1; match_index >= start_match; --match_index) {
size_t len_test = enc->matches[match_index].length; size_t len_test = enc->matches[match_index].length;
@@ -1348,12 +1348,12 @@ static size_t LZMA_initMatchesPos0Best(LZMA2_ECtx *const enc, FL2_dataBlock cons
FORCE_INLINE_TEMPLATE FORCE_INLINE_TEMPLATE
size_t LZMA_initOptimizerPos0(LZMA2_ECtx *const enc, FL2_dataBlock const block, size_t LZMA_initOptimizerPos0(LZMA2_ECtx *const enc, FL2_dataBlock const block,
RMF_match const match, RMF_match const match,
size_t const index, size_t const pos,
int const is_hybrid, int const is_hybrid,
U32* const reps) U32* const reps)
{ {
size_t const max_length = MIN(block.end - index, kMatchLenMax); size_t const max_length = MIN(block.end - pos, kMatchLenMax);
const BYTE *const data = block.data + index; const BYTE *const data = block.data + pos;
const BYTE *data_2; const BYTE *data_2;
size_t rep_max_index = 0; size_t rep_max_index = 0;
size_t rep_lens[kNumReps]; size_t rep_lens[kNumReps];
@@ -1384,14 +1384,14 @@ size_t LZMA_initOptimizerPos0(LZMA2_ECtx *const enc, FL2_dataBlock const block,
unsigned const cur_byte = *data; unsigned const cur_byte = *data;
unsigned const match_byte = *(data - reps[0] - 1); unsigned const match_byte = *(data - reps[0] - 1);
size_t const state = enc->states.state; size_t const state = enc->states.state;
size_t const pos_state = index & enc->pos_mask; size_t const pos_state = pos & enc->pos_mask;
Probability const is_match_prob = enc->states.is_match[state][pos_state]; LZMA2_prob const is_match_prob = enc->states.is_match[state][pos_state];
Probability const is_rep_prob = enc->states.is_rep[state]; LZMA2_prob const is_rep_prob = enc->states.is_rep[state];
enc->opt_buf[0].state = state; enc->opt_buf[0].state = state;
/* Set the price for literal */ /* Set the price for literal */
enc->opt_buf[1].price = GET_PRICE_0(is_match_prob) + enc->opt_buf[1].price = GET_PRICE_0(is_match_prob) +
LZMA_getLiteralPrice(enc, index, state, data[-1], cur_byte, match_byte); LZMA_getLiteralPrice(enc, pos, state, data[-1], cur_byte, match_byte);
MARK_LITERAL(enc->opt_buf[1]); MARK_LITERAL(enc->opt_buf[1]);
unsigned const match_price = GET_PRICE_1(is_match_prob); unsigned const match_price = GET_PRICE_1(is_match_prob);
@@ -1434,7 +1434,7 @@ size_t LZMA_initOptimizerPos0(LZMA2_ECtx *const enc, FL2_dataBlock const block,
} }
else { else {
/* Hybrid mode */ /* Hybrid mode */
size_t main_len = LZMA_initMatchesPos0Best(enc, block, match, index, len, normal_match_price); size_t main_len = LZMA_initMatchesPos0Best(enc, block, match, pos, len, normal_match_price);
return MAX(main_len, rep_lens[rep_max_index]); return MAX(main_len, rep_lens[rep_max_index]);
} }
} }
@@ -1464,16 +1464,16 @@ size_t LZMA_encodeOptimumSequence(LZMA2_ECtx *const enc, FL2_dataBlock const blo
} }
/* Set everything up at position 0 */ /* Set everything up at position 0 */
size_t index = start_index; size_t pos = start_index;
U32 reps[kNumReps]; U32 reps[kNumReps];
len_end = LZMA_initOptimizerPos0(enc, block, match, index, is_hybrid, reps); len_end = LZMA_initOptimizerPos0(enc, block, match, pos, is_hybrid, reps);
match.length = 0; match.length = 0;
size_t cur = 1; size_t cur = 1;
/* len_end == 0 if a match of fast_length was found */ /* len_end == 0 if a match of fast_length was found */
if (len_end > 0) { if (len_end > 0) {
++index; ++pos;
for (; cur < len_end; ++cur, ++index) { for (; cur < len_end; ++cur, ++pos) {
/* Terminate if the farthest calculated price is too near the buffer end */ /* Terminate if the farthest calculated price is too near the buffer end */
if (len_end >= kOptimizerBufferSize - kOptimizerEndSize) { if (len_end >= kOptimizerBufferSize - kOptimizerEndSize) {
U32 price = enc->opt_buf[cur].price; U32 price = enc->opt_buf[cur].price;
@@ -1498,18 +1498,18 @@ size_t LZMA_encodeOptimumSequence(LZMA2_ECtx *const enc, FL2_dataBlock const blo
U32 const price2 = enc->opt_buf[j].price; U32 const price2 = enc->opt_buf[j].price;
if (price >= price2) { if (price >= price2) {
price = price2; price = price2;
index += j - cur; pos += j - cur;
cur = j; cur = j;
if (cur == len_end) if (cur == len_end)
goto reverse; goto reverse;
} }
} }
match = RMF_getMatch(block, tbl, search_depth, struct_tbl, index); match = RMF_getMatch(block, tbl, search_depth, struct_tbl, pos);
if (match.length >= enc->fast_length) if (match.length >= enc->fast_length)
break; break;
len_end = LZMA_optimalParse(enc, block, match, index, cur, len_end, is_hybrid, reps); len_end = LZMA_optimalParse(enc, block, match, pos, cur, len_end, is_hybrid, reps);
} }
reverse: reverse:
DEBUGLOG(6, "End optimal parse at %u", (U32)cur); DEBUGLOG(6, "End optimal parse at %u", (U32)cur);
@@ -1555,7 +1555,7 @@ reverse:
static void FORCE_NOINLINE LZMA_fillAlignPrices(LZMA2_ECtx *const enc) static void FORCE_NOINLINE LZMA_fillAlignPrices(LZMA2_ECtx *const enc)
{ {
unsigned i; unsigned i;
const Probability *const probs = enc->states.dist_align_encoders; const LZMA2_prob *const probs = enc->states.dist_align_encoders;
for (i = 0; i < kAlignTableSize / 2; i++) { for (i = 0; i < kAlignTableSize / 2; i++) {
U32 price = 0; U32 price = 0;
unsigned sym = i; unsigned sym = i;
@@ -1580,7 +1580,7 @@ static void FORCE_NOINLINE LZMA_fillDistancesPrices(LZMA2_ECtx *const enc)
unsigned const dist_slot = distance_table[i]; unsigned const dist_slot = distance_table[i];
unsigned footer_bits = (dist_slot >> 1) - 1; unsigned footer_bits = (dist_slot >> 1) - 1;
size_t base = ((2 | (dist_slot & 1)) << footer_bits); size_t base = ((2 | (dist_slot & 1)) << footer_bits);
const Probability *probs = enc->states.dist_encoders + base * 2U; const LZMA2_prob *probs = enc->states.dist_encoders + base * 2U;
base += i; base += i;
probs = probs - distance_table[base] - 1; probs = probs - distance_table[base] - 1;
U32 price = 0; U32 price = 0;
@@ -1604,7 +1604,7 @@ static void FORCE_NOINLINE LZMA_fillDistancesPrices(LZMA2_ECtx *const enc)
size_t slot; size_t slot;
size_t const dist_table_size2 = (enc->dist_price_table_size + 1) >> 1; size_t const dist_table_size2 = (enc->dist_price_table_size + 1) >> 1;
U32 *const dist_slot_prices = enc->dist_slot_prices[lps]; U32 *const dist_slot_prices = enc->dist_slot_prices[lps];
const Probability *const probs = enc->states.dist_slot_encoders[lps]; const LZMA2_prob *const probs = enc->states.dist_slot_encoders[lps];
for (slot = 0; slot < dist_table_size2; slot++) { for (slot = 0; slot < dist_table_size2; slot++) {
/* dist_slot_prices[slot] = RcTree_GetPrice(encoder, kNumPosSlotBits, slot, p->ProbPrices); */ /* dist_slot_prices[slot] = RcTree_GetPrice(encoder, kNumPosSlotBits, slot, p->ProbPrices); */
@@ -1652,7 +1652,7 @@ size_t LZMA_encodeChunkBest(LZMA2_ECtx *const enc,
FL2_dataBlock const block, FL2_dataBlock const block,
FL2_matchTable* const tbl, FL2_matchTable* const tbl,
int const struct_tbl, int const struct_tbl,
size_t index, size_t pos,
size_t const uncompressed_end) size_t const uncompressed_end)
{ {
unsigned const search_depth = tbl->params.depth; unsigned const search_depth = tbl->params.depth;
@@ -1661,16 +1661,16 @@ size_t LZMA_encodeChunkBest(LZMA2_ECtx *const enc,
LZMA_lengthStates_updatePrices(enc, &enc->states.len_states); LZMA_lengthStates_updatePrices(enc, &enc->states.len_states);
LZMA_lengthStates_updatePrices(enc, &enc->states.rep_len_states); LZMA_lengthStates_updatePrices(enc, &enc->states.rep_len_states);
while (index < uncompressed_end && enc->rc.out_index < enc->chunk_size) while (pos < uncompressed_end && enc->rc.out_index < enc->chunk_size)
{ {
RMF_match const match = RMF_getMatch(block, tbl, search_depth, struct_tbl, index); RMF_match const match = RMF_getMatch(block, tbl, search_depth, struct_tbl, pos);
if (match.length > 1) { if (match.length > 1) {
/* Template-like inline function */ /* Template-like inline function */
if (enc->strategy == FL2_ultra) { if (enc->strategy == FL2_ultra) {
index = LZMA_encodeOptimumSequence(enc, block, tbl, struct_tbl, 1, index, uncompressed_end, match); pos = LZMA_encodeOptimumSequence(enc, block, tbl, struct_tbl, 1, pos, uncompressed_end, match);
} }
else { else {
index = LZMA_encodeOptimumSequence(enc, block, tbl, struct_tbl, 0, index, uncompressed_end, match); pos = LZMA_encodeOptimumSequence(enc, block, tbl, struct_tbl, 0, pos, uncompressed_end, match);
} }
if (enc->match_price_count >= kMatchRepriceFrequency) { if (enc->match_price_count >= kMatchRepriceFrequency) {
LZMA_fillAlignPrices(enc); LZMA_fillAlignPrices(enc);
@@ -1683,20 +1683,20 @@ size_t LZMA_encodeChunkBest(LZMA2_ECtx *const enc,
} }
} }
else { else {
if (block.data[index] != block.data[index - enc->states.reps[0] - 1]) { if (block.data[pos] != block.data[pos - enc->states.reps[0] - 1]) {
LZMA_encodeLiteralBuf(enc, block.data, index); LZMA_encodeLiteralBuf(enc, block.data, pos);
++index; ++pos;
} }
else { else {
LZMA_encodeRepMatchShort(enc, index & enc->pos_mask); LZMA_encodeRepMatchShort(enc, pos & enc->pos_mask);
++index; ++pos;
} }
} }
} }
return index; return pos;
} }
static void LZMA_lengthStates_Reset(LengthStates* const ls, unsigned const fast_length) static void LZMA_lengthStates_Reset(LZMA2_lenStates* const ls, unsigned const fast_length)
{ {
ls->choice = kProbInitValue; ls->choice = kProbInitValue;
@@ -1709,7 +1709,7 @@ static void LZMA_lengthStates_Reset(LengthStates* const ls, unsigned const fast_
ls->table_size = fast_length + 1 - kMatchLenMin; ls->table_size = fast_length + 1 - kMatchLenMin;
} }
static void LZMA_encoderStates_Reset(EncoderStates* const es, unsigned const lc, unsigned const lp, unsigned fast_length) static void LZMA_encoderStates_Reset(LZMA2_encStates* const es, unsigned const lc, unsigned const lp, unsigned fast_length)
{ {
es->state = 0; es->state = 0;
@@ -1731,7 +1731,7 @@ static void LZMA_encoderStates_Reset(EncoderStates* const es, unsigned const lc,
es->literal_probs[i] = kProbInitValue; es->literal_probs[i] = kProbInitValue;
for (size_t i = 0; i < kNumLenToPosStates; ++i) { for (size_t i = 0; i < kNumLenToPosStates; ++i) {
Probability *probs = es->dist_slot_encoders[i]; LZMA2_prob *probs = es->dist_slot_encoders[i];
for (size_t j = 0; j < (1 << kNumPosSlotBits); ++j) for (size_t j = 0; j < (1 << kNumPosSlotBits); ++j)
probs[j] = kProbInitValue; probs[j] = kProbInitValue;
} }
@@ -1775,7 +1775,7 @@ size_t LZMA2_encMemoryUsage(unsigned const chain_log, FL2_strategy const strateg
{ {
size_t size = sizeof(LZMA2_ECtx); size_t size = sizeof(LZMA2_ECtx);
if(strategy == FL2_ultra) if(strategy == FL2_ultra)
size += sizeof(HashChains) + (sizeof(U32) << chain_log) - sizeof(U32); size += sizeof(LZMA2_hc3) + (sizeof(U32) << chain_log) - sizeof(U32);
return size * thread_count; return size * thread_count;
} }
@@ -1837,16 +1837,16 @@ static BYTE LZMA2_isChunkIncompressible(const FL2_matchTable* const tbl,
if (tbl->is_struct) { if (tbl->is_struct) {
size_t prev_dist = 0; size_t prev_dist = 0;
for (size_t index = start; index < end; ) { for (size_t pos = start; pos < end; ) {
U32 const link = GetMatchLink(tbl->table, index); U32 const link = GetMatchLink(tbl->table, pos);
if (link == RADIX_NULL_LINK) { if (link == RADIX_NULL_LINK) {
++index; ++pos;
++count; ++count;
prev_dist = 0; prev_dist = 0;
} }
else { else {
size_t const length = GetMatchLength(tbl->table, index); size_t const length = GetMatchLength(tbl->table, pos);
size_t const dist = index - GetMatchLink(tbl->table, index); size_t const dist = pos - GetMatchLink(tbl->table, pos);
if (length > 4) { if (length > 4) {
/* Increase the cost if it's not the same match */ /* Increase the cost if it's not the same match */
count += dist != prev_dist; count += dist != prev_dist;
@@ -1855,33 +1855,33 @@ static BYTE LZMA2_isChunkIncompressible(const FL2_matchTable* const tbl,
/* Increment the cost for a short match. The cost is the entire length if it's too far */ /* Increment the cost for a short match. The cost is the entire length if it's too far */
count += (dist < max_dist_table[strategy][length]) ? 1 : length; count += (dist < max_dist_table[strategy][length]) ? 1 : length;
} }
index += length; pos += length;
prev_dist = dist; prev_dist = dist;
} }
if (count + terminator <= index) if (count + terminator <= pos)
return 0; return 0;
} }
} }
else { else {
size_t prev_dist = 0; size_t prev_dist = 0;
for (size_t index = start; index < end; ) { for (size_t pos = start; pos < end; ) {
U32 const link = tbl->table[index]; U32 const link = tbl->table[pos];
if (link == RADIX_NULL_LINK) { if (link == RADIX_NULL_LINK) {
++index; ++pos;
++count; ++count;
prev_dist = 0; prev_dist = 0;
} }
else { else {
size_t const length = link >> RADIX_LINK_BITS; size_t const length = link >> RADIX_LINK_BITS;
size_t const dist = index - (link & RADIX_LINK_MASK); size_t const dist = pos - (link & RADIX_LINK_MASK);
if (length > 4) if (length > 4)
count += dist != prev_dist; count += dist != prev_dist;
else else
count += (dist < max_dist_table[strategy][length]) ? 1 : length; count += (dist < max_dist_table[strategy][length]) ? 1 : length;
index += length; pos += length;
prev_dist = dist; prev_dist = dist;
} }
if (count + terminator <= index) if (count + terminator <= pos)
return 0; return 0;
} }
} }
@@ -1892,8 +1892,8 @@ static BYTE LZMA2_isChunkIncompressible(const FL2_matchTable* const tbl,
U32 const avg = (U32)(chunk_size / 64U); U32 const avg = (U32)(chunk_size / 64U);
memset(char_count, 0, sizeof(char_count)); memset(char_count, 0, sizeof(char_count));
for (size_t index = start; index < end; ++index) for (size_t pos = start; pos < end; ++pos)
char_count[block.data[index]] += 4; char_count[block.data[pos]] += 4;
/* Sum the deviations */ /* Sum the deviations */
for (size_t i = 0; i < 256; ++i) { for (size_t i = 0; i < 256; ++i) {
S32 delta = char_count[i] - avg; S32 delta = char_count[i] - avg;
@@ -1909,27 +1909,27 @@ static BYTE LZMA2_isChunkIncompressible(const FL2_matchTable* const tbl,
static size_t LZMA2_encodeChunk(LZMA2_ECtx *const enc, static size_t LZMA2_encodeChunk(LZMA2_ECtx *const enc,
FL2_matchTable* const tbl, FL2_matchTable* const tbl,
FL2_dataBlock const block, FL2_dataBlock const block,
size_t const index, size_t const uncompressed_end) size_t const pos, size_t const uncompressed_end)
{ {
/* Template-like inline functions */ /* Template-like inline functions */
if (enc->strategy == FL2_fast) { if (enc->strategy == FL2_fast) {
if (tbl->is_struct) { if (tbl->is_struct) {
return LZMA_encodeChunkFast(enc, block, tbl, 1, return LZMA_encodeChunkFast(enc, block, tbl, 1,
index, uncompressed_end); pos, uncompressed_end);
} }
else { else {
return LZMA_encodeChunkFast(enc, block, tbl, 0, return LZMA_encodeChunkFast(enc, block, tbl, 0,
index, uncompressed_end); pos, uncompressed_end);
} }
} }
else { else {
if (tbl->is_struct) { if (tbl->is_struct) {
return LZMA_encodeChunkBest(enc, block, tbl, 1, return LZMA_encodeChunkBest(enc, block, tbl, 1,
index, uncompressed_end); pos, uncompressed_end);
} }
else { else {
return LZMA_encodeChunkBest(enc, block, tbl, 0, return LZMA_encodeChunkBest(enc, block, tbl, 0,
index, uncompressed_end); pos, uncompressed_end);
} }
} }
} }
@@ -1987,28 +1987,28 @@ size_t LZMA2_encode(LZMA2_ECtx *const enc,
/* Limit the matches near the end of this slice to not exceed block.end */ /* Limit the matches near the end of this slice to not exceed block.end */
RMF_limitLengths(tbl, block.end); RMF_limitLengths(tbl, block.end);
for (size_t index = start; index < block.end;) { for (size_t pos = start; pos < block.end;) {
size_t header_size = (stream_prop >= 0) + (encode_properties ? kChunkHeaderSize + 1 : kChunkHeaderSize); size_t header_size = (stream_prop >= 0) + (encode_properties ? kChunkHeaderSize + 1 : kChunkHeaderSize);
EncoderStates saved_states; LZMA2_encStates saved_states;
size_t next_index; size_t next_index;
RC_reset(&enc->rc); RC_reset(&enc->rc);
RC_setOutputBuffer(&enc->rc, out_dest + header_size); RC_setOutputBuffer(&enc->rc, out_dest + header_size);
if (!incompressible) { if (!incompressible) {
size_t cur = index; size_t cur = pos;
size_t const end = (enc->strategy == FL2_fast) ? MIN(block.end, index + kMaxChunkUncompressedSize - kMatchLenMax + 1) size_t const end = (enc->strategy == FL2_fast) ? MIN(block.end, pos + kMaxChunkUncompressedSize - kMatchLenMax + 1)
: MIN(block.end, index + kMaxChunkUncompressedSize - kOptimizerBufferSize + 2); /* last byte of opt_buf unused */ : MIN(block.end, pos + kMaxChunkUncompressedSize - kOptimizerBufferSize + 2); /* last byte of opt_buf unused */
/* Copy states in case chunk is incompressible */ /* Copy states in case chunk is incompressible */
saved_states = enc->states; saved_states = enc->states;
if (index == 0) { if (pos == 0) {
/* First byte of the dictionary */ /* First byte of the dictionary */
LZMA_encodeLiteral(enc, 0, block.data[0], 0); LZMA_encodeLiteral(enc, 0, block.data[0], 0);
++cur; ++cur;
} }
if (index == start) { if (pos == start) {
/* After kTempMinOutput bytes we can write data to the match table because the */ /* After kTempMinOutput bytes we can write data to the match table because the */
/* compressed data will never catch up with the table position being read. */ /* compressed data will never catch up with the table position being read. */
cur = LZMA2_encodeChunk(enc, tbl, block, cur, end); cur = LZMA2_encodeChunk(enc, tbl, block, cur, end);
@@ -2029,10 +2029,10 @@ size_t LZMA2_encode(LZMA2_ECtx *const enc,
RC_flush(&enc->rc); RC_flush(&enc->rc);
} }
else { else {
next_index = MIN(index + kChunkSize, block.end); next_index = MIN(pos + kChunkSize, block.end);
} }
size_t compressed_size = enc->rc.out_index; size_t compressed_size = enc->rc.out_index;
size_t uncompressed_size = next_index - index; size_t uncompressed_size = next_index - pos;
if (compressed_size > kMaxChunkCompressedSize || uncompressed_size > kMaxChunkUncompressedSize) if (compressed_size > kMaxChunkCompressedSize || uncompressed_size > kMaxChunkUncompressedSize)
return FL2_ERROR(internal); return FL2_ERROR(internal);
@@ -2050,10 +2050,10 @@ size_t LZMA2_encode(LZMA2_ECtx *const enc,
if (incompressible || uncompressed_size + 3 <= compressed_size + header_size) { if (incompressible || uncompressed_size + 3 <= compressed_size + header_size) {
DEBUGLOG(6, "Storing chunk : was %u => %u", (unsigned)uncompressed_size, (unsigned)compressed_size); DEBUGLOG(6, "Storing chunk : was %u => %u", (unsigned)uncompressed_size, (unsigned)compressed_size);
header[0] = (index == 0) ? kChunkUncompressedDictReset : kChunkUncompressed; header[0] = (pos == 0) ? kChunkUncompressedDictReset : kChunkUncompressed;
/* Copy uncompressed data into the output */ /* Copy uncompressed data into the output */
memcpy(header + 3, block.data + index, uncompressed_size); memcpy(header + 3, block.data + pos, uncompressed_size);
compressed_size = uncompressed_size; compressed_size = uncompressed_size;
header_size = 3 + (header - out_dest); header_size = 3 + (header - out_dest);
@@ -2065,7 +2065,7 @@ size_t LZMA2_encode(LZMA2_ECtx *const enc,
else { else {
DEBUGLOG(6, "Compressed chunk : %u => %u", (unsigned)uncompressed_size, (unsigned)compressed_size); DEBUGLOG(6, "Compressed chunk : %u => %u", (unsigned)uncompressed_size, (unsigned)compressed_size);
if (index == 0) if (pos == 0)
header[0] = kChunkCompressedFlag | kChunkAllReset; header[0] = kChunkCompressedFlag | kChunkAllReset;
else if (encode_properties) else if (encode_properties)
header[0] = kChunkCompressedFlag | kChunkStatePropertiesReset; header[0] = kChunkCompressedFlag | kChunkStatePropertiesReset;
@@ -2087,10 +2087,10 @@ size_t LZMA2_encode(LZMA2_ECtx *const enc,
out_dest += compressed_size + header_size; out_dest += compressed_size + header_size;
/* Update progress concurrently with other encoder threads */ /* Update progress concurrently with other encoder threads */
FL2_atomic_add(*progress_in, (long)(next_index - index)); FL2_atomic_add(*progress_in, (long)(next_index - pos));
FL2_atomic_add(*progress_out, (long)(compressed_size + header_size)); FL2_atomic_add(*progress_out, (long)(compressed_size + header_size));
index = next_index; pos = next_index;
if (*canceled) if (*canceled)
return FL2_ERROR(canceled); return FL2_ERROR(canceled);

View File

@@ -13,8 +13,6 @@
#include "fl2_internal.h" #include "fl2_internal.h"
#include "radix_internal.h" #include "radix_internal.h"
typedef struct FL2_matchTable_s FL2_matchTable;
#undef MIN #undef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -22,38 +20,38 @@ typedef struct FL2_matchTable_s FL2_matchTable;
#define RADIX_MAX_LENGTH BITPACK_MAX_LENGTH #define RADIX_MAX_LENGTH BITPACK_MAX_LENGTH
#define InitMatchLink(index, link) tbl->table[index] = link #define InitMatchLink(pos, link) tbl->table[pos] = link
#define GetMatchLink(link) (tbl->table[link] & RADIX_LINK_MASK) #define GetMatchLink(link) (tbl->table[link] & RADIX_LINK_MASK)
#define GetInitialMatchLink(index) tbl->table[index] #define GetInitialMatchLink(pos) tbl->table[pos]
#define GetMatchLength(index) (tbl->table[index] >> RADIX_LINK_BITS) #define GetMatchLength(pos) (tbl->table[pos] >> RADIX_LINK_BITS)
#define SetMatchLink(index, link, length) tbl->table[index] = (link) | ((U32)(length) << RADIX_LINK_BITS) #define SetMatchLink(pos, link, length) tbl->table[pos] = (link) | ((U32)(length) << RADIX_LINK_BITS)
#define SetMatchLength(index, link, length) tbl->table[index] = (link) | ((U32)(length) << RADIX_LINK_BITS) #define SetMatchLength(pos, link, length) tbl->table[pos] = (link) | ((U32)(length) << RADIX_LINK_BITS)
#define SetMatchLinkAndLength(index, link, length) tbl->table[index] = (link) | ((U32)(length) << RADIX_LINK_BITS) #define SetMatchLinkAndLength(pos, link, length) tbl->table[pos] = (link) | ((U32)(length) << RADIX_LINK_BITS)
#define SetNull(index) tbl->table[index] = RADIX_NULL_LINK #define SetNull(pos) tbl->table[pos] = RADIX_NULL_LINK
#define IsNull(index) (tbl->table[index] == RADIX_NULL_LINK) #define IsNull(pos) (tbl->table[pos] == RADIX_NULL_LINK)
BYTE* RMF_bitpackAsOutputBuffer(FL2_matchTable* const tbl, size_t const index) BYTE* RMF_bitpackAsOutputBuffer(FL2_matchTable* const tbl, size_t const pos)
{ {
return (BYTE*)(tbl->table + index); return (BYTE*)(tbl->table + pos);
} }
/* Restrict the match lengths so that they don't reach beyond index */ /* Restrict the match lengths so that they don't reach beyond pos */
void RMF_bitpackLimitLengths(FL2_matchTable* const tbl, size_t const index) void RMF_bitpackLimitLengths(FL2_matchTable* const tbl, size_t const pos)
{ {
DEBUGLOG(5, "RMF_limitLengths : end %u, max length %u", (U32)index, RADIX_MAX_LENGTH); DEBUGLOG(5, "RMF_limitLengths : end %u, max length %u", (U32)pos, RADIX_MAX_LENGTH);
SetNull(index - 1); SetNull(pos - 1);
for (U32 length = 2; length < RADIX_MAX_LENGTH && length <= index; ++length) { for (U32 length = 2; length < RADIX_MAX_LENGTH && length <= pos; ++length) {
U32 const link = tbl->table[index - length]; U32 const link = tbl->table[pos - length];
if (link != RADIX_NULL_LINK) if (link != RADIX_NULL_LINK)
tbl->table[index - length] = (MIN(length, link >> RADIX_LINK_BITS) << RADIX_LINK_BITS) | (link & RADIX_LINK_MASK); tbl->table[pos - length] = (MIN(length, link >> RADIX_LINK_BITS) << RADIX_LINK_BITS) | (link & RADIX_LINK_MASK);
} }
} }

View File

@@ -103,7 +103,7 @@ static void RMF_initReference(FL2_matchTable* const tbl, const void* const data,
} }
#endif #endif
size_t void
#ifdef RMF_BITPACK #ifdef RMF_BITPACK
RMF_bitpackInit RMF_bitpackInit
#else #else
@@ -115,12 +115,12 @@ RMF_structuredInit
for (size_t i = 0; i < end; ++i) for (size_t i = 0; i < end; ++i)
SetNull(i); SetNull(i);
tbl->end_index = 0; tbl->end_index = 0;
return 0; return;
} }
#ifdef RMF_REFERENCE #ifdef RMF_REFERENCE
if (tbl->params.use_ref_mf) { if (tbl->params.use_ref_mf) {
RMF_initReference(tbl, data, end); RMF_initReference(tbl, data, end);
return 0; return;
} }
#endif #endif
@@ -136,7 +136,6 @@ RMF_structuredInit
radix_16 = ((size_t)((BYTE)radix_16) << 8) | data_block[2]; radix_16 = ((size_t)((BYTE)radix_16) << 8) | data_block[2];
ptrdiff_t rpt_total = 0;
ptrdiff_t i = 1; ptrdiff_t i = 1;
ptrdiff_t const block_size = end - 2; ptrdiff_t const block_size = end - 2;
for (; i < block_size; ++i) { for (; i < block_size; ++i) {
@@ -170,8 +169,6 @@ RMF_structuredInit
SetNull(end - 1); SetNull(end - 1);
tbl->end_index = (U32)st_index; tbl->end_index = (U32)st_index;
return rpt_total;
} }
/* Copy the list into a buffer and recurse it there. This decreases cache misses and allows */ /* Copy the list into a buffer and recurse it there. This decreases cache misses and allows */
@@ -264,23 +261,23 @@ static void RMF_recurseListsBuffered(RMF_builder* const tbl,
/* Copy everything back, except the last link which never changes, and any extra overlap */ /* Copy everything back, except the last link which never changes, and any extra overlap */
count -= overlap + (overlap == 0); count -= overlap + (overlap == 0);
#ifdef RMF_BITPACK #ifdef RMF_BITPACK
if (max_depth > RADIX_MAX_LENGTH) for (size_t index = 0; index < count; ++index) { if (max_depth > RADIX_MAX_LENGTH) for (size_t pos = 0; pos < count; ++pos) {
size_t const from = tbl->match_buffer[index].from; size_t const from = tbl->match_buffer[pos].from;
if (from < block_start) if (from < block_start)
return; return;
U32 length = tbl->match_buffer[index].next >> 24; U32 length = tbl->match_buffer[pos].next >> 24;
length = (length > RADIX_MAX_LENGTH) ? RADIX_MAX_LENGTH : length; length = (length > RADIX_MAX_LENGTH) ? RADIX_MAX_LENGTH : length;
size_t const next = tbl->match_buffer[index].next & BUFFER_LINK_MASK; size_t const next = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
SetMatchLinkAndLength(from, tbl->match_buffer[next].from, length); SetMatchLinkAndLength(from, tbl->match_buffer[next].from, length);
} }
else else
#endif #endif
for (size_t index = 0; index < count; ++index) { for (size_t pos = 0; pos < count; ++pos) {
size_t const from = tbl->match_buffer[index].from; size_t const from = tbl->match_buffer[pos].from;
if (from < block_start) if (from < block_start)
return; return;
U32 const length = tbl->match_buffer[index].next >> 24; U32 const length = tbl->match_buffer[pos].next >> 24;
size_t const next = tbl->match_buffer[index].next & BUFFER_LINK_MASK; size_t const next = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
SetMatchLinkAndLength(from, tbl->match_buffer[next].from, length); SetMatchLinkAndLength(from, tbl->match_buffer[next].from, length);
} }
start = 0; start = 0;
@@ -338,32 +335,32 @@ static void RMF_recurseListsBound(RMF_builder* const tbl,
/* Create an offset data buffer pointer for reading the next bytes */ /* Create an offset data buffer pointer for reading the next bytes */
const BYTE* data_src = data_block + 2; const BYTE* data_src = data_block + 2;
U32 depth = 3; U32 depth = 3;
size_t index = 0; size_t pos = 0;
size_t st_index = 0; size_t st_index = 0;
RMF_listTail* const tails_8 = tbl->tails_8; RMF_listTail* const tails_8 = tbl->tails_8;
do { do {
link = tbl->match_buffer[index].from; link = tbl->match_buffer[pos].from;
if (link < limit) { if (link < limit) {
size_t const radix_8 = data_src[link]; size_t const radix_8 = data_src[link];
/* Seen this char before? */ /* Seen this char before? */
U32 const prev = tails_8[radix_8].prev_index; U32 const prev = tails_8[radix_8].prev_index;
tails_8[radix_8].prev_index = (U32)index; tails_8[radix_8].prev_index = (U32)pos;
if (prev != RADIX_NULL_LINK) { if (prev != RADIX_NULL_LINK) {
++tails_8[radix_8].list_count; ++tails_8[radix_8].list_count;
/* Link the previous occurrence to this one and record the new length */ /* Link the previous occurrence to this one and record the new length */
tbl->match_buffer[prev].next = (U32)index | (depth << 24); tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
} }
else { else {
tails_8[radix_8].list_count = 1; tails_8[radix_8].list_count = 1;
/* Add the new sub list to the stack */ /* Add the new sub list to the stack */
tbl->stack[st_index].head = (U32)index; tbl->stack[st_index].head = (U32)pos;
/* This will be converted to a count at the end */ /* This will be converted to a count at the end */
tbl->stack[st_index].count = (U32)radix_8; tbl->stack[st_index].count = (U32)radix_8;
++st_index; ++st_index;
} }
} }
++index; ++pos;
} while (index < list_count); } while (pos < list_count);
/* Convert radix values on the stack to counts and reset any used tail slots */ /* Convert radix values on the stack to counts and reset any used tail slots */
for (size_t j = 0; j < st_index; ++j) { for (size_t j = 0; j < st_index; ++j) {
tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK; tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK;
@@ -378,11 +375,11 @@ static void RMF_recurseListsBound(RMF_builder* const tbl,
if (list_count < 2) /* Nothing to match with */ if (list_count < 2) /* Nothing to match with */
continue; continue;
index = tbl->stack[st_index].head; pos = tbl->stack[st_index].head;
depth = (tbl->match_buffer[index].next >> 24); depth = (tbl->match_buffer[pos].next >> 24);
if (depth >= max_depth) if (depth >= max_depth)
continue; continue;
link = tbl->match_buffer[index].from; link = tbl->match_buffer[pos].from;
if (link < bounded_start) { if (link < bounded_start) {
/* Chain starts before the bounded region */ /* Chain starts before the bounded region */
continue; continue;
@@ -392,23 +389,23 @@ static void RMF_recurseListsBound(RMF_builder* const tbl,
++depth; ++depth;
prev_st_index = st_index; prev_st_index = st_index;
do { do {
link = tbl->match_buffer[index].from; link = tbl->match_buffer[pos].from;
if (link < limit) { if (link < limit) {
size_t const radix_8 = data_src[link]; size_t const radix_8 = data_src[link];
U32 const prev = tails_8[radix_8].prev_index; U32 const prev = tails_8[radix_8].prev_index;
tails_8[radix_8].prev_index = (U32)index; tails_8[radix_8].prev_index = (U32)pos;
if (prev != RADIX_NULL_LINK) { if (prev != RADIX_NULL_LINK) {
++tails_8[radix_8].list_count; ++tails_8[radix_8].list_count;
tbl->match_buffer[prev].next = (U32)index | (depth << 24); tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
} }
else { else {
tails_8[radix_8].list_count = 1; tails_8[radix_8].list_count = 1;
tbl->stack[st_index].head = (U32)index; tbl->stack[st_index].head = (U32)pos;
tbl->stack[st_index].count = (U32)radix_8; tbl->stack[st_index].count = (U32)radix_8;
++st_index; ++st_index;
} }
} }
index = tbl->match_buffer[index].next & BUFFER_LINK_MASK; pos = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
} while (--list_count != 0); } while (--list_count != 0);
for (size_t j = prev_st_index; j < st_index; ++j) { for (size_t j = prev_st_index; j < st_index; ++j) {
tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK; tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK;
@@ -417,16 +414,16 @@ static void RMF_recurseListsBound(RMF_builder* const tbl,
} }
/* Copy everything back above the bound */ /* Copy everything back above the bound */
--count; --count;
for (index = 0; index < count; ++index) { for (pos = 0; pos < count; ++pos) {
ptrdiff_t const from = tbl->match_buffer[index].from; ptrdiff_t const from = tbl->match_buffer[pos].from;
if (from < bounded_start) if (from < bounded_start)
break; break;
U32 length = tbl->match_buffer[index].next >> 24; U32 length = tbl->match_buffer[pos].next >> 24;
length = MIN(length, (U32)(block_size - from)); length = MIN(length, (U32)(block_size - from));
length = MIN(length, RADIX_MAX_LENGTH); length = MIN(length, RADIX_MAX_LENGTH);
size_t const next = tbl->match_buffer[index].next & BUFFER_LINK_MASK; size_t const next = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
SetMatchLinkAndLength(from, tbl->match_buffer[next].from, length); SetMatchLinkAndLength(from, tbl->match_buffer[next].from, length);
} }
} }
@@ -901,9 +898,9 @@ static void RMF_recurseListsReference(RMF_builder* const tbl,
static ptrdiff_t RMF_getNextList_mt(FL2_matchTable* const tbl) static ptrdiff_t RMF_getNextList_mt(FL2_matchTable* const tbl)
{ {
if (tbl->st_index < tbl->end_index) { if (tbl->st_index < tbl->end_index) {
long index = FL2_atomic_increment(tbl->st_index); long pos = FL2_atomic_increment(tbl->st_index);
if (index < tbl->end_index) if (pos < tbl->end_index)
return index; return pos;
} }
return -1; return -1;
} }
@@ -912,9 +909,9 @@ static ptrdiff_t RMF_getNextList_mt(FL2_matchTable* const tbl)
static ptrdiff_t RMF_getNextList_st(FL2_matchTable* const tbl) static ptrdiff_t RMF_getNextList_st(FL2_matchTable* const tbl)
{ {
if (tbl->st_index < tbl->end_index) { if (tbl->st_index < tbl->end_index) {
long index = FL2_nonAtomic_increment(tbl->st_index); long pos = FL2_nonAtomic_increment(tbl->st_index);
if (index < tbl->end_index) if (pos < tbl->end_index)
return index; return pos;
} }
return -1; return -1;
} }
@@ -927,7 +924,7 @@ RMF_bitpackBuildTable
RMF_structuredBuildTable RMF_structuredBuildTable
#endif #endif
(FL2_matchTable* const tbl, (FL2_matchTable* const tbl,
size_t const job, size_t const job,
unsigned const multi_thread, unsigned const multi_thread,
FL2_dataBlock const block) FL2_dataBlock const block)
{ {
@@ -945,19 +942,19 @@ RMF_structuredBuildTable
for (;;) for (;;)
{ {
/* Get the next to process */ /* Get the next to process */
ptrdiff_t index = getNextList(tbl); ptrdiff_t pos = getNextList(tbl);
if (index < 0) if (pos < 0)
break; break;
while (next_progress < index) { while (next_progress < pos) {
/* initial value of next_progress ensures only thread 0 executes this */ /* initial value of next_progress ensures only thread 0 executes this */
tbl->progress += tbl->list_heads[tbl->stack[next_progress]].count; tbl->progress += tbl->list_heads[tbl->stack[next_progress]].count;
++next_progress; ++next_progress;
} }
index = tbl->stack[index]; pos = tbl->stack[pos];
RMF_tableHead list_head = tbl->list_heads[index]; RMF_tableHead list_head = tbl->list_heads[pos];
tbl->list_heads[index].head = RADIX_NULL_LINK; tbl->list_heads[pos].head = RADIX_NULL_LINK;
if (list_head.count < 2 || list_head.head < block.start) if (list_head.count < 2 || list_head.head < block.start)
continue; continue;
@@ -989,33 +986,33 @@ RMF_bitpackIntegrityCheck
#else #else
RMF_structuredIntegrityCheck RMF_structuredIntegrityCheck
#endif #endif
(const FL2_matchTable* const tbl, const BYTE* const data, size_t index, size_t const end, unsigned max_depth) (const FL2_matchTable* const tbl, const BYTE* const data, size_t pos, size_t const end, unsigned max_depth)
{ {
max_depth &= ~1; max_depth &= ~1;
int err = 0; int err = 0;
for (index += !index; index < end; ++index) { for (pos += !pos; pos < end; ++pos) {
if (IsNull(index)) if (IsNull(pos))
continue; continue;
U32 const link = GetMatchLink(index); U32 const link = GetMatchLink(pos);
if (link >= index) { if (link >= pos) {
printf("Forward link at %X to %u\r\n", (U32)index, link); printf("Forward link at %X to %u\r\n", (U32)pos, link);
err = 1; err = 1;
continue; continue;
} }
U32 const length = GetMatchLength(index); U32 const length = GetMatchLength(pos);
if (index && length < RADIX_MAX_LENGTH && link - 1 == GetMatchLink(index - 1) && length + 1 == GetMatchLength(index - 1)) if (pos && length < RADIX_MAX_LENGTH && link - 1 == GetMatchLink(pos - 1) && length + 1 == GetMatchLength(pos - 1))
continue; continue;
U32 len_test = 0; U32 len_test = 0;
U32 const limit = MIN((U32)(end - index), RADIX_MAX_LENGTH); U32 const limit = MIN((U32)(end - pos), RADIX_MAX_LENGTH);
for (; len_test < limit && data[link + len_test] == data[index + len_test]; ++len_test) { for (; len_test < limit && data[link + len_test] == data[pos + len_test]; ++len_test) {
} }
if (len_test < length) { if (len_test < length) {
printf("Failed integrity check: pos %X, length %u, actual %u\r\n", (U32)index, length, len_test); printf("Failed integrity check: pos %X, length %u, actual %u\r\n", (U32)pos, length, len_test);
err = 1; err = 1;
} }
if (length < max_depth && len_test > length) if (length < max_depth && len_test > length)
/* These occur occasionally due to splitting of chains in the buffer when long repeats are present */ /* These occur occasionally due to splitting of chains in the buffer when long repeats are present */
printf("Shortened match at %X: %u of %u\r\n", (U32)index, length, len_test); printf("Shortened match at %X: %u of %u\r\n", (U32)pos, length, len_test);
} }
return err; return err;
} }

View File

@@ -49,9 +49,9 @@ static size_t RMF_bitpackExtendMatch(const BYTE* const data,
return end_index - start_index; return end_index - start_index;
} }
#define GetMatchLink(table, index) ((const RMF_unit*)(table))[(index) >> UNIT_BITS].links[(index) & UNIT_MASK] #define GetMatchLink(table, pos) ((const RMF_unit*)(table))[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK]
#define GetMatchLength(table, index) ((const RMF_unit*)(table))[(index) >> UNIT_BITS].lengths[(index) & UNIT_MASK] #define GetMatchLength(table, pos) ((const RMF_unit*)(table))[(pos) >> UNIT_BITS].lengths[(pos) & UNIT_MASK]
static size_t RMF_structuredExtendMatch(const BYTE* const data, static size_t RMF_structuredExtendMatch(const BYTE* const data,
const U32* const table, const U32* const table,
@@ -86,11 +86,11 @@ RMF_match RMF_getMatch(FL2_dataBlock block,
FL2_matchTable* tbl, FL2_matchTable* tbl,
unsigned max_depth, unsigned max_depth,
int structTbl, int structTbl,
size_t index) size_t pos)
{ {
if (structTbl) if (structTbl)
{ {
U32 const link = GetMatchLink(tbl->table, index); U32 const link = GetMatchLink(tbl->table, pos);
RMF_match match; RMF_match match;
match.length = 0; match.length = 0;
@@ -98,11 +98,11 @@ RMF_match RMF_getMatch(FL2_dataBlock block,
if (link == RADIX_NULL_LINK) if (link == RADIX_NULL_LINK)
return match; return match;
size_t const length = GetMatchLength(tbl->table, index); size_t const length = GetMatchLength(tbl->table, pos);
size_t const dist = index - link - 1; size_t const dist = pos - link - 1;
if (length == max_depth || length == STRUCTURED_MAX_LENGTH /* from HandleRepeat */) if (length == max_depth || length == STRUCTURED_MAX_LENGTH /* from HandleRepeat */)
match.length = (U32)RMF_structuredExtendMatch(block.data, tbl->table, index, block.end, link, length); match.length = (U32)RMF_structuredExtendMatch(block.data, tbl->table, pos, block.end, link, length);
else else
match.length = (U32)length; match.length = (U32)length;
@@ -111,7 +111,7 @@ RMF_match RMF_getMatch(FL2_dataBlock block,
return match; return match;
} }
else { else {
U32 link = tbl->table[index]; U32 link = tbl->table[pos];
RMF_match match; RMF_match match;
match.length = 0; match.length = 0;
@@ -121,10 +121,10 @@ RMF_match RMF_getMatch(FL2_dataBlock block,
size_t const length = link >> RADIX_LINK_BITS; size_t const length = link >> RADIX_LINK_BITS;
link &= RADIX_LINK_MASK; link &= RADIX_LINK_MASK;
size_t const dist = index - link - 1; size_t const dist = pos - link - 1;
if (length == max_depth || length == BITPACK_MAX_LENGTH /* from HandleRepeat */) if (length == max_depth || length == BITPACK_MAX_LENGTH /* from HandleRepeat */)
match.length = (U32)RMF_bitpackExtendMatch(block.data, tbl->table, index, block.end, link, length); match.length = (U32)RMF_bitpackExtendMatch(block.data, tbl->table, pos, block.end, link, length);
else else
match.length = (U32)length; match.length = (U32)length;
@@ -139,11 +139,11 @@ RMF_match RMF_getNextMatch(FL2_dataBlock block,
FL2_matchTable* tbl, FL2_matchTable* tbl,
unsigned max_depth, unsigned max_depth,
int structTbl, int structTbl,
size_t index) size_t pos)
{ {
if (structTbl) if (structTbl)
{ {
U32 const link = GetMatchLink(tbl->table, index); U32 const link = GetMatchLink(tbl->table, pos);
RMF_match match; RMF_match match;
match.length = 0; match.length = 0;
@@ -151,15 +151,15 @@ RMF_match RMF_getNextMatch(FL2_dataBlock block,
if (link == RADIX_NULL_LINK) if (link == RADIX_NULL_LINK)
return match; return match;
size_t const length = GetMatchLength(tbl->table, index); size_t const length = GetMatchLength(tbl->table, pos);
size_t const dist = index - link - 1; size_t const dist = pos - link - 1;
/* same distance, one byte shorter */ /* same distance, one byte shorter */
if (link - 1 == GetMatchLink(tbl->table, index - 1)) if (link - 1 == GetMatchLink(tbl->table, pos - 1))
return match; return match;
if (length == max_depth || length == STRUCTURED_MAX_LENGTH /* from HandleRepeat */) if (length == max_depth || length == STRUCTURED_MAX_LENGTH /* from HandleRepeat */)
match.length = (U32)RMF_structuredExtendMatch(block.data, tbl->table, index, block.end, link, length); match.length = (U32)RMF_structuredExtendMatch(block.data, tbl->table, pos, block.end, link, length);
else else
match.length = (U32)length; match.length = (U32)length;
@@ -168,7 +168,7 @@ RMF_match RMF_getNextMatch(FL2_dataBlock block,
return match; return match;
} }
else { else {
U32 link = tbl->table[index]; U32 link = tbl->table[pos];
RMF_match match; RMF_match match;
match.length = 0; match.length = 0;
@@ -178,14 +178,14 @@ RMF_match RMF_getNextMatch(FL2_dataBlock block,
size_t const length = link >> RADIX_LINK_BITS; size_t const length = link >> RADIX_LINK_BITS;
link &= RADIX_LINK_MASK; link &= RADIX_LINK_MASK;
size_t const dist = index - link - 1; size_t const dist = pos - link - 1;
/* same distance, one byte shorter */ /* same distance, one byte shorter */
if (link - 1 == (tbl->table[index - 1] & RADIX_LINK_MASK)) if (link - 1 == (tbl->table[pos - 1] & RADIX_LINK_MASK))
return match; return match;
if (length == max_depth || length == BITPACK_MAX_LENGTH /* from HandleRepeat */) if (length == max_depth || length == BITPACK_MAX_LENGTH /* from HandleRepeat */)
match.length = (U32)RMF_bitpackExtendMatch(block.data, tbl->table, index, block.end, link, length); match.length = (U32)RMF_bitpackExtendMatch(block.data, tbl->table, pos, block.end, link, length);
else else
match.length = (U32)length; match.length = (U32)length;

View File

@@ -54,14 +54,14 @@ typedef struct
} RMF_tableHead; } RMF_tableHead;
union src_data_u { union src_data_u {
BYTE chars[4]; BYTE chars[4];
U32 u32; U32 u32;
}; };
typedef struct typedef struct
{ {
U32 from; U32 from;
union src_data_u src; union src_data_u src;
U32 next; U32 next;
} RMF_buildMatch; } RMF_buildMatch;
@@ -105,14 +105,14 @@ struct FL2_matchTable_s
U32 table[1]; U32 table[1];
}; };
size_t RMF_bitpackInit(struct FL2_matchTable_s* const tbl, const void* data, size_t const end); void RMF_bitpackInit(struct FL2_matchTable_s* const tbl, const void* data, size_t const end);
size_t RMF_structuredInit(struct FL2_matchTable_s* const tbl, const void* data, size_t const end); void RMF_structuredInit(struct FL2_matchTable_s* const tbl, const void* data, size_t const end);
void RMF_bitpackBuildTable(struct FL2_matchTable_s* const tbl, void RMF_bitpackBuildTable(struct FL2_matchTable_s* const tbl,
size_t const job, size_t const job,
unsigned const multi_thread, unsigned const multi_thread,
FL2_dataBlock const block); FL2_dataBlock const block);
void RMF_structuredBuildTable(struct FL2_matchTable_s* const tbl, void RMF_structuredBuildTable(struct FL2_matchTable_s* const tbl,
size_t const job, size_t const job,
unsigned const multi_thread, unsigned const multi_thread,
FL2_dataBlock const block); FL2_dataBlock const block);
void RMF_recurseListChunk(RMF_builder* const tbl, void RMF_recurseListChunk(RMF_builder* const tbl,
@@ -122,21 +122,21 @@ void RMF_recurseListChunk(RMF_builder* const tbl,
U32 const max_depth, U32 const max_depth,
U32 const list_count, U32 const list_count,
size_t const stack_base); size_t const stack_base);
int RMF_bitpackIntegrityCheck(const struct FL2_matchTable_s* const tbl, const BYTE* const data, size_t index, size_t const end, unsigned max_depth); int RMF_bitpackIntegrityCheck(const struct FL2_matchTable_s* const tbl, const BYTE* const data, size_t pos, size_t const end, unsigned max_depth);
int RMF_structuredIntegrityCheck(const struct FL2_matchTable_s* const tbl, const BYTE* const data, size_t index, size_t const end, unsigned max_depth); int RMF_structuredIntegrityCheck(const struct FL2_matchTable_s* const tbl, const BYTE* const data, size_t pos, size_t const end, unsigned max_depth);
void RMF_bitpackLimitLengths(struct FL2_matchTable_s* const tbl, size_t const index); void RMF_bitpackLimitLengths(struct FL2_matchTable_s* const tbl, size_t const pos);
void RMF_structuredLimitLengths(struct FL2_matchTable_s* const tbl, size_t const index); void RMF_structuredLimitLengths(struct FL2_matchTable_s* const tbl, size_t const pos);
BYTE* RMF_bitpackAsOutputBuffer(struct FL2_matchTable_s* const tbl, size_t const index); BYTE* RMF_bitpackAsOutputBuffer(struct FL2_matchTable_s* const tbl, size_t const pos);
BYTE* RMF_structuredAsOutputBuffer(struct FL2_matchTable_s* const tbl, size_t const index); BYTE* RMF_structuredAsOutputBuffer(struct FL2_matchTable_s* const tbl, size_t const pos);
size_t RMF_bitpackGetMatch(const struct FL2_matchTable_s* const tbl, size_t RMF_bitpackGetMatch(const struct FL2_matchTable_s* const tbl,
const BYTE* const data, const BYTE* const data,
size_t const index, size_t const pos,
size_t const limit, size_t const limit,
unsigned const max_depth, unsigned const max_depth,
size_t* const offset_ptr); size_t* const offset_ptr);
size_t RMF_structuredGetMatch(const struct FL2_matchTable_s* const tbl, size_t RMF_structuredGetMatch(const struct FL2_matchTable_s* const tbl,
const BYTE* const data, const BYTE* const data,
size_t const index, size_t const pos,
size_t const limit, size_t const limit,
unsigned const max_depth, unsigned const max_depth,
size_t* const offset_ptr); size_t* const offset_ptr);

View File

@@ -16,7 +16,7 @@
#include "fl2_internal.h" #include "fl2_internal.h"
#include "radix_internal.h" #include "radix_internal.h"
#ifdef __GNUC__ #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" /* warning: 'rpt_head_next' may be used uninitialized in this function */ # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" /* warning: 'rpt_head_next' may be used uninitialized in this function */
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
# pragma warning(disable : 4701) /* warning: 'rpt_head_next' may be used uninitialized in this function */ # pragma warning(disable : 4701) /* warning: 'rpt_head_next' may be used uninitialized in this function */
@@ -274,16 +274,16 @@ void RMF_initProgress(FL2_matchTable * const tbl)
tbl->progress = 0; tbl->progress = 0;
} }
size_t RMF_initTable(FL2_matchTable* const tbl, const void* const data, size_t const end) void RMF_initTable(FL2_matchTable* const tbl, const void* const data, size_t const end)
{ {
DEBUGLOG(5, "RMF_initTable : size %u", (U32)end); DEBUGLOG(5, "RMF_initTable : size %u", (U32)end);
tbl->st_index = ATOMIC_INITIAL_VALUE; tbl->st_index = ATOMIC_INITIAL_VALUE;
if (tbl->is_struct) if (tbl->is_struct)
return RMF_structuredInit(tbl, data, end); RMF_structuredInit(tbl, data, end);
else else
return RMF_bitpackInit(tbl, data, end); RMF_bitpackInit(tbl, data, end);
} }
static void RMF_handleRepeat(RMF_buildMatch* const match_buffer, static void RMF_handleRepeat(RMF_buildMatch* const match_buffer,
@@ -294,31 +294,31 @@ static void RMF_handleRepeat(RMF_buildMatch* const match_buffer,
U32 const depth, U32 const depth,
U32 const max_len) U32 const max_len)
{ {
size_t index = next; size_t pos = next;
U32 length = depth + rpt_len; U32 length = depth + rpt_len;
const BYTE* const data = data_block + match_buffer[index].from; const BYTE* const data = data_block + match_buffer[pos].from;
const BYTE* const data_2 = data - rpt_len; const BYTE* const data_2 = data - rpt_len;
while (data[length] == data_2[length] && length < max_len) while (data[length] == data_2[length] && length < max_len)
++length; ++length;
for (; length <= max_len && count; --count) { for (; length <= max_len && count; --count) {
size_t next_i = match_buffer[index].next & 0xFFFFFF; size_t next_i = match_buffer[pos].next & 0xFFFFFF;
match_buffer[index].next = (U32)next_i | (length << 24); match_buffer[pos].next = (U32)next_i | (length << 24);
length += rpt_len; length += rpt_len;
index = next_i; pos = next_i;
} }
for (; count; --count) { for (; count; --count) {
size_t next_i = match_buffer[index].next & 0xFFFFFF; size_t next_i = match_buffer[pos].next & 0xFFFFFF;
match_buffer[index].next = (U32)next_i | (max_len << 24); match_buffer[pos].next = (U32)next_i | (max_len << 24);
index = next_i; pos = next_i;
} }
} }
typedef struct typedef struct
{ {
size_t index; size_t pos;
const BYTE* data_src; const BYTE* data_src;
union src_data_u src; union src_data_u src;
} BruteForceMatch; } BruteForceMatch;
@@ -326,7 +326,7 @@ typedef struct
static void RMF_bruteForceBuffered(RMF_builder* const tbl, static void RMF_bruteForceBuffered(RMF_builder* const tbl,
const BYTE* const data_block, const BYTE* const data_block,
size_t const block_start, size_t const block_start,
size_t index, size_t pos,
size_t const list_count, size_t const list_count,
size_t const slot, size_t const slot,
size_t const depth, size_t const depth,
@@ -339,14 +339,14 @@ static void RMF_bruteForceBuffered(RMF_builder* const tbl,
size_t i = 0; size_t i = 0;
for (;;) { for (;;) {
/* Load all locations from the match buffer */ /* Load all locations from the match buffer */
buffer[i].index = index; buffer[i].pos = pos;
buffer[i].data_src = data_src + tbl->match_buffer[index].from; buffer[i].data_src = data_src + tbl->match_buffer[pos].from;
buffer[i].src.u32 = tbl->match_buffer[index].src.u32; buffer[i].src.u32 = tbl->match_buffer[pos].src.u32;
if (++i >= list_count) if (++i >= list_count)
break; break;
index = tbl->match_buffer[index].next & 0xFFFFFF; pos = tbl->match_buffer[pos].next & 0xFFFFFF;
} }
i = 0; i = 0;
do { do {
@@ -376,8 +376,8 @@ static void RMF_bruteForceBuffered(RMF_builder* const tbl,
} while (++j < list_count); } while (++j < list_count);
if (longest > 0) { if (longest > 0) {
/* If the existing match was extended, store the new link and length info in the match buffer */ /* If the existing match was extended, store the new link and length info in the match buffer */
index = buffer[i].index; pos = buffer[i].pos;
tbl->match_buffer[index].next = (U32)(buffer[longest_index].index | ((depth + longest) << 24)); tbl->match_buffer[pos].next = (U32)(buffer[longest_index].pos | ((depth + longest) << 24));
} }
++i; ++i;
} while (i < list_count - 1 && buffer[i].data_src >= start); } while (i < list_count - 1 && buffer[i].data_src >= start);
@@ -397,38 +397,38 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
{ {
U32 const base_depth = depth; U32 const base_depth = depth;
size_t st_index = stack_base; size_t st_index = stack_base;
size_t index = 0; size_t pos = 0;
++depth; ++depth;
/* The last element is done separately and won't be copied back at the end */ /* The last element is done separately and won't be copied back at the end */
--list_count; --list_count;
do { do {
size_t const radix_8 = tbl->match_buffer[index].src.chars[0]; size_t const radix_8 = tbl->match_buffer[pos].src.chars[0];
/* Seen this char before? */ /* Seen this char before? */
U32 const prev = tbl->tails_8[radix_8].prev_index; U32 const prev = tbl->tails_8[radix_8].prev_index;
tbl->tails_8[radix_8].prev_index = (U32)index; tbl->tails_8[radix_8].prev_index = (U32)pos;
if (prev != RADIX_NULL_LINK) { if (prev != RADIX_NULL_LINK) {
++tbl->tails_8[radix_8].list_count; ++tbl->tails_8[radix_8].list_count;
/* Link the previous occurrence to this one and record the new length */ /* Link the previous occurrence to this one and record the new length */
tbl->match_buffer[prev].next = (U32)index | (depth << 24); tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
} }
else { else {
tbl->tails_8[radix_8].list_count = 1; tbl->tails_8[radix_8].list_count = 1;
/* Add the new sub list to the stack */ /* Add the new sub list to the stack */
tbl->stack[st_index].head = (U32)index; tbl->stack[st_index].head = (U32)pos;
/* This will be converted to a count at the end */ /* This will be converted to a count at the end */
tbl->stack[st_index].count = (U32)radix_8; tbl->stack[st_index].count = (U32)radix_8;
++st_index; ++st_index;
} }
++index; ++pos;
} while (index < list_count); } while (pos < list_count);
{ /* Do the last element */ { /* Do the last element */
size_t const radix_8 = tbl->match_buffer[index].src.chars[0]; size_t const radix_8 = tbl->match_buffer[pos].src.chars[0];
/* Nothing to do if there was no previous */ /* Nothing to do if there was no previous */
U32 const prev = tbl->tails_8[radix_8].prev_index; U32 const prev = tbl->tails_8[radix_8].prev_index;
if (prev != RADIX_NULL_LINK) { if (prev != RADIX_NULL_LINK) {
++tbl->tails_8[radix_8].list_count; ++tbl->tails_8[radix_8].list_count;
tbl->match_buffer[prev].next = (U32)index | (depth << 24); tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
} }
} }
/* Convert radix values on the stack to counts and reset any used tail slots */ /* Convert radix values on the stack to counts and reset any used tail slots */
@@ -444,8 +444,8 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
/* Nothing to match with */ /* Nothing to match with */
continue; continue;
} }
index = tbl->stack[st_index].head; pos = tbl->stack[st_index].head;
size_t link = tbl->match_buffer[index].from; size_t link = tbl->match_buffer[pos].from;
if (link < block_start) { if (link < block_start) {
/* Chain starts in the overlap region which is already encoded */ /* Chain starts in the overlap region which is already encoded */
continue; continue;
@@ -457,7 +457,7 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
/* Stack may not be able to fit all possible new items. This is very rare. */ /* Stack may not be able to fit all possible new items. This is very rare. */
continue; continue;
} }
depth = tbl->match_buffer[index].next >> 24; depth = tbl->match_buffer[pos].next >> 24;
/* Index into the 4-byte pre-loaded input char cache */ /* Index into the 4-byte pre-loaded input char cache */
size_t slot = (depth - base_depth) & 3; size_t slot = (depth - base_depth) & 3;
if (list_count <= MAX_BRUTE_FORCE_LIST_SIZE) { if (list_count <= MAX_BRUTE_FORCE_LIST_SIZE) {
@@ -465,7 +465,7 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
RMF_bruteForceBuffered(tbl, RMF_bruteForceBuffered(tbl,
data_block, data_block,
block_start, block_start,
index, pos,
list_count, list_count,
slot, slot,
depth, depth,
@@ -486,59 +486,59 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
--list_count; --list_count;
/* If slot is 3 then chars need to be loaded. */ /* If slot is 3 then chars need to be loaded. */
if (slot == 3 && max_depth != 6) do { if (slot == 3 && max_depth != 6) do {
size_t const radix_8 = tbl->match_buffer[index].src.chars[3]; size_t const radix_8 = tbl->match_buffer[pos].src.chars[3];
size_t const next_index = tbl->match_buffer[index].next & BUFFER_LINK_MASK; size_t const next_index = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
/* Pre-load the next link and data bytes. On some hardware execution can continue /* Pre-load the next link and data bytes. On some hardware execution can continue
* ahead while the data is retrieved if no operations except move are done on the data. */ * ahead while the data is retrieved if no operations except move are done on the data. */
tbl->match_buffer[index].src.u32 = MEM_read32(data_src + link); tbl->match_buffer[pos].src.u32 = MEM_read32(data_src + link);
size_t const next_link = tbl->match_buffer[next_index].from; size_t const next_link = tbl->match_buffer[next_index].from;
U32 const prev = tbl->tails_8[radix_8].prev_index; U32 const prev = tbl->tails_8[radix_8].prev_index;
tbl->tails_8[radix_8].prev_index = (U32)index; tbl->tails_8[radix_8].prev_index = (U32)pos;
if (prev != RADIX_NULL_LINK) { if (prev != RADIX_NULL_LINK) {
/* This char has occurred before in the chain. Link the previous (> index) occurance with this */ /* This char has occurred before in the chain. Link the previous (> pos) occurance with this */
++tbl->tails_8[radix_8].list_count; ++tbl->tails_8[radix_8].list_count;
tbl->match_buffer[prev].next = (U32)index | (depth << 24); tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
} }
else { else {
/* First occurrence in the chain */ /* First occurrence in the chain */
tbl->tails_8[radix_8].list_count = 1; tbl->tails_8[radix_8].list_count = 1;
tbl->stack[st_index].head = (U32)index; tbl->stack[st_index].head = (U32)pos;
/* Save the char as a reference to load the count at the end */ /* Save the char as a reference to load the count at the end */
tbl->stack[st_index].count = (U32)radix_8; tbl->stack[st_index].count = (U32)radix_8;
++st_index; ++st_index;
} }
index = next_index; pos = next_index;
link = next_link; link = next_link;
} while (--list_count != 0); } while (--list_count != 0);
else do { else do {
size_t const radix_8 = tbl->match_buffer[index].src.chars[slot]; size_t const radix_8 = tbl->match_buffer[pos].src.chars[slot];
size_t const next_index = tbl->match_buffer[index].next & BUFFER_LINK_MASK; size_t const next_index = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
/* Pre-load the next link to avoid waiting for RAM access */ /* Pre-load the next link to avoid waiting for RAM access */
size_t const next_link = tbl->match_buffer[next_index].from; size_t const next_link = tbl->match_buffer[next_index].from;
U32 const prev = tbl->tails_8[radix_8].prev_index; U32 const prev = tbl->tails_8[radix_8].prev_index;
tbl->tails_8[radix_8].prev_index = (U32)index; tbl->tails_8[radix_8].prev_index = (U32)pos;
if (prev != RADIX_NULL_LINK) { if (prev != RADIX_NULL_LINK) {
++tbl->tails_8[radix_8].list_count; ++tbl->tails_8[radix_8].list_count;
tbl->match_buffer[prev].next = (U32)index | (depth << 24); tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
} }
else { else {
tbl->tails_8[radix_8].list_count = 1; tbl->tails_8[radix_8].list_count = 1;
tbl->stack[st_index].head = (U32)index; tbl->stack[st_index].head = (U32)pos;
tbl->stack[st_index].count = (U32)radix_8; tbl->stack[st_index].count = (U32)radix_8;
++st_index; ++st_index;
} }
index = next_index; pos = next_index;
link = next_link; link = next_link;
} while (--list_count != 0); } while (--list_count != 0);
size_t const radix_8 = tbl->match_buffer[index].src.chars[slot]; size_t const radix_8 = tbl->match_buffer[pos].src.chars[slot];
U32 const prev = tbl->tails_8[radix_8].prev_index; U32 const prev = tbl->tails_8[radix_8].prev_index;
if (prev != RADIX_NULL_LINK) { if (prev != RADIX_NULL_LINK) {
if (slot == 3) if (slot == 3)
tbl->match_buffer[index].src.u32 = MEM_read32(data_src + link); tbl->match_buffer[pos].src.u32 = MEM_read32(data_src + link);
++tbl->tails_8[radix_8].list_count; ++tbl->tails_8[radix_8].list_count;
tbl->match_buffer[prev].next = (U32)index | (depth << 24); tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
} }
for (size_t j = prev_st_index; j < st_index; ++j) { for (size_t j = prev_st_index; j < st_index; ++j) {
tbl->tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK; tbl->tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK;
@@ -554,8 +554,8 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
/* Last element done separately */ /* Last element done separately */
--list_count; --list_count;
do { do {
size_t const radix_8 = tbl->match_buffer[index].src.chars[slot]; size_t const radix_8 = tbl->match_buffer[pos].src.chars[slot];
size_t const next_index = tbl->match_buffer[index].next & BUFFER_LINK_MASK; size_t const next_index = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
size_t const next_link = tbl->match_buffer[next_index].from; size_t const next_link = tbl->match_buffer[next_index].from;
if ((link - next_link) > rpt_depth) { if ((link - next_link) > rpt_depth) {
if (rpt > 0) if (rpt > 0)
@@ -563,18 +563,18 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
rpt = -1; rpt = -1;
U32 const prev = tbl->tails_8[radix_8].prev_index; U32 const prev = tbl->tails_8[radix_8].prev_index;
tbl->tails_8[radix_8].prev_index = (U32)index; tbl->tails_8[radix_8].prev_index = (U32)pos;
if (prev != RADIX_NULL_LINK) { if (prev != RADIX_NULL_LINK) {
++tbl->tails_8[radix_8].list_count; ++tbl->tails_8[radix_8].list_count;
tbl->match_buffer[prev].next = (U32)index | (depth << 24); tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
} }
else { else {
tbl->tails_8[radix_8].list_count = 1; tbl->tails_8[radix_8].list_count = 1;
tbl->stack[st_index].head = (U32)index; tbl->stack[st_index].head = (U32)pos;
tbl->stack[st_index].count = (U32)radix_8; tbl->stack[st_index].count = (U32)radix_8;
++st_index; ++st_index;
} }
index = next_index; pos = next_index;
link = next_link; link = next_link;
} }
else { else {
@@ -587,14 +587,14 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
rpt_head_next = next_index; rpt_head_next = next_index;
rpt_dist = dist; rpt_dist = dist;
U32 const prev = tbl->tails_8[radix_8].prev_index; U32 const prev = tbl->tails_8[radix_8].prev_index;
tbl->tails_8[radix_8].prev_index = (U32)index; tbl->tails_8[radix_8].prev_index = (U32)pos;
if (prev != RADIX_NULL_LINK) { if (prev != RADIX_NULL_LINK) {
++tbl->tails_8[radix_8].list_count; ++tbl->tails_8[radix_8].list_count;
tbl->match_buffer[prev].next = (U32)index | (depth << 24); tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
} }
else { else {
tbl->tails_8[radix_8].list_count = 1; tbl->tails_8[radix_8].list_count = 1;
tbl->stack[st_index].head = (U32)index; tbl->stack[st_index].head = (U32)pos;
tbl->stack[st_index].count = (U32)radix_8; tbl->stack[st_index].count = (U32)radix_8;
++st_index; ++st_index;
} }
@@ -602,7 +602,7 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
else { else {
++rpt; ++rpt;
} }
index = next_index; pos = next_index;
link = next_link; link = next_link;
} }
} while (--list_count != 0); } while (--list_count != 0);
@@ -610,14 +610,14 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
if (rpt > 0) if (rpt > 0)
RMF_handleRepeat(tbl->match_buffer, data_block, rpt_head_next, rpt, rpt_dist, rpt_depth, tbl->max_len); RMF_handleRepeat(tbl->match_buffer, data_block, rpt_head_next, rpt, rpt_dist, rpt_depth, tbl->max_len);
size_t const radix_8 = tbl->match_buffer[index].src.chars[slot]; size_t const radix_8 = tbl->match_buffer[pos].src.chars[slot];
U32 const prev = tbl->tails_8[radix_8].prev_index; U32 const prev = tbl->tails_8[radix_8].prev_index;
if (prev != RADIX_NULL_LINK) { if (prev != RADIX_NULL_LINK) {
if (slot == 3) { if (slot == 3) {
tbl->match_buffer[index].src.u32 = MEM_read32(data_src + link); tbl->match_buffer[pos].src.u32 = MEM_read32(data_src + link);
} }
++tbl->tails_8[radix_8].list_count; ++tbl->tails_8[radix_8].list_count;
tbl->match_buffer[prev].next = (U32)index | (depth << 24); tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
} }
for (size_t j = prev_st_index; j < st_index; ++j) { for (size_t j = prev_st_index; j < st_index; ++j) {
tbl->tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK; tbl->tails_8[tbl->stack[j].count].prev_index = RADIX_NULL_LINK;
@@ -628,21 +628,21 @@ void RMF_recurseListChunk_generic(RMF_builder* const tbl,
size_t const prev_st_index = st_index; size_t const prev_st_index = st_index;
/* The last pass at max_depth */ /* The last pass at max_depth */
do { do {
size_t const radix_8 = tbl->match_buffer[index].src.chars[slot]; size_t const radix_8 = tbl->match_buffer[pos].src.chars[slot];
size_t const next_index = tbl->match_buffer[index].next & BUFFER_LINK_MASK; size_t const next_index = tbl->match_buffer[pos].next & BUFFER_LINK_MASK;
/* Pre-load the next link. */ /* Pre-load the next link. */
/* The last element in tbl->match_buffer is circular so this is never an access violation. */ /* The last element in tbl->match_buffer is circular so this is never an access violation. */
size_t const next_link = tbl->match_buffer[next_index].from; size_t const next_link = tbl->match_buffer[next_index].from;
U32 const prev = tbl->tails_8[radix_8].prev_index; U32 const prev = tbl->tails_8[radix_8].prev_index;
tbl->tails_8[radix_8].prev_index = (U32)index; tbl->tails_8[radix_8].prev_index = (U32)pos;
if (prev != RADIX_NULL_LINK) { if (prev != RADIX_NULL_LINK) {
tbl->match_buffer[prev].next = (U32)index | (depth << 24); tbl->match_buffer[prev].next = (U32)pos | (depth << 24);
} }
else { else {
tbl->stack[st_index].count = (U32)radix_8; tbl->stack[st_index].count = (U32)radix_8;
++st_index; ++st_index;
} }
index = next_index; pos = next_index;
link = next_link; link = next_link;
} while (--list_count != 0); } while (--list_count != 0);
for (size_t j = prev_st_index; j < st_index; ++j) { for (size_t j = prev_st_index; j < st_index; ++j) {
@@ -703,28 +703,28 @@ void RMF_resetIncompleteBuild(FL2_matchTable * const tbl)
RMF_initListHeads(tbl); RMF_initListHeads(tbl);
} }
int RMF_integrityCheck(const FL2_matchTable* const tbl, const BYTE* const data, size_t const index, size_t const end, unsigned const max_depth) int RMF_integrityCheck(const FL2_matchTable* const tbl, const BYTE* const data, size_t const pos, size_t const end, unsigned const max_depth)
{ {
if (tbl->is_struct) if (tbl->is_struct)
return RMF_structuredIntegrityCheck(tbl, data, index, end, max_depth); return RMF_structuredIntegrityCheck(tbl, data, pos, end, max_depth);
else else
return RMF_bitpackIntegrityCheck(tbl, data, index, end, max_depth); return RMF_bitpackIntegrityCheck(tbl, data, pos, end, max_depth);
} }
void RMF_limitLengths(FL2_matchTable* const tbl, size_t const index) void RMF_limitLengths(FL2_matchTable* const tbl, size_t const pos)
{ {
if (tbl->is_struct) if (tbl->is_struct)
RMF_structuredLimitLengths(tbl, index); RMF_structuredLimitLengths(tbl, pos);
else else
RMF_bitpackLimitLengths(tbl, index); RMF_bitpackLimitLengths(tbl, pos);
} }
BYTE* RMF_getTableAsOutputBuffer(FL2_matchTable* const tbl, size_t const index) BYTE* RMF_getTableAsOutputBuffer(FL2_matchTable* const tbl, size_t const pos)
{ {
if (tbl->is_struct) if (tbl->is_struct)
return RMF_structuredAsOutputBuffer(tbl, index); return RMF_structuredAsOutputBuffer(tbl, pos);
else else
return RMF_bitpackAsOutputBuffer(tbl, index); return RMF_bitpackAsOutputBuffer(tbl, pos);
} }
size_t RMF_memoryUsage(size_t const dict_size, unsigned const buffer_resize, unsigned const thread_count) size_t RMF_memoryUsage(size_t const dict_size, unsigned const buffer_resize, unsigned const thread_count)

View File

@@ -42,16 +42,16 @@ BYTE RMF_compatibleParameters(const FL2_matchTable* const tbl, const RMF_paramet
size_t RMF_applyParameters(FL2_matchTable* const tbl, const RMF_parameters* const params, size_t const dict_reduce); size_t RMF_applyParameters(FL2_matchTable* const tbl, const RMF_parameters* const params, size_t const dict_reduce);
size_t RMF_threadCount(const FL2_matchTable * const tbl); size_t RMF_threadCount(const FL2_matchTable * const tbl);
void RMF_initProgress(FL2_matchTable * const tbl); void RMF_initProgress(FL2_matchTable * const tbl);
size_t RMF_initTable(FL2_matchTable* const tbl, const void* const data, size_t const end); void RMF_initTable(FL2_matchTable* const tbl, const void* const data, size_t const end);
int RMF_buildTable(FL2_matchTable* const tbl, int RMF_buildTable(FL2_matchTable* const tbl,
size_t const job, size_t const job,
unsigned const multi_thread, unsigned const multi_thread,
FL2_dataBlock const block); FL2_dataBlock const block);
void RMF_cancelBuild(FL2_matchTable* const tbl); void RMF_cancelBuild(FL2_matchTable* const tbl);
void RMF_resetIncompleteBuild(FL2_matchTable* const tbl); void RMF_resetIncompleteBuild(FL2_matchTable* const tbl);
int RMF_integrityCheck(const FL2_matchTable* const tbl, const BYTE* const data, size_t const index, size_t const end, unsigned const max_depth); int RMF_integrityCheck(const FL2_matchTable* const tbl, const BYTE* const data, size_t const pos, size_t const end, unsigned const max_depth);
void RMF_limitLengths(FL2_matchTable* const tbl, size_t const index); void RMF_limitLengths(FL2_matchTable* const tbl, size_t const pos);
BYTE* RMF_getTableAsOutputBuffer(FL2_matchTable* const tbl, size_t const index); BYTE* RMF_getTableAsOutputBuffer(FL2_matchTable* const tbl, size_t const pos);
size_t RMF_memoryUsage(size_t const dict_size, unsigned const buffer_resize, unsigned const thread_count); size_t RMF_memoryUsage(size_t const dict_size, unsigned const buffer_resize, unsigned const thread_count);
#if defined (__cplusplus) #if defined (__cplusplus)

View File

@@ -13,8 +13,6 @@
#include "fl2_internal.h" #include "fl2_internal.h"
#include "radix_internal.h" #include "radix_internal.h"
typedef struct FL2_matchTable_s FL2_matchTable;
#undef MIN #undef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -22,37 +20,37 @@ typedef struct FL2_matchTable_s FL2_matchTable;
#define RADIX_MAX_LENGTH STRUCTURED_MAX_LENGTH #define RADIX_MAX_LENGTH STRUCTURED_MAX_LENGTH
#define InitMatchLink(index, link) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK] = (U32)(link) #define InitMatchLink(pos, link) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK] = (U32)(link)
#define GetMatchLink(index) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK] #define GetMatchLink(pos) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK]
#define GetInitialMatchLink(index) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK] #define GetInitialMatchLink(pos) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK]
#define GetMatchLength(index) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].lengths[(index) & UNIT_MASK] #define GetMatchLength(pos) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].lengths[(pos) & UNIT_MASK]
#define SetMatchLink(index, link, length) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK] = (U32)(link) #define SetMatchLink(pos, link, length) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK] = (U32)(link)
#define SetMatchLength(index, link, length) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].lengths[(index) & UNIT_MASK] = (BYTE)(length) #define SetMatchLength(pos, link, length) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].lengths[(pos) & UNIT_MASK] = (BYTE)(length)
#define SetMatchLinkAndLength(index, link, length) do { size_t i_ = (index) >> UNIT_BITS, u_ = (index) & UNIT_MASK; ((RMF_unit*)tbl->table)[i_].links[u_] = (U32)(link); ((RMF_unit*)tbl->table)[i_].lengths[u_] = (BYTE)(length); } while(0) #define SetMatchLinkAndLength(pos, link, length) do { size_t i_ = (pos) >> UNIT_BITS, u_ = (pos) & UNIT_MASK; ((RMF_unit*)tbl->table)[i_].links[u_] = (U32)(link); ((RMF_unit*)tbl->table)[i_].lengths[u_] = (BYTE)(length); } while(0)
#define SetNull(index) ((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK] = RADIX_NULL_LINK #define SetNull(pos) ((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK] = RADIX_NULL_LINK
#define IsNull(index) (((RMF_unit*)tbl->table)[(index) >> UNIT_BITS].links[(index) & UNIT_MASK] == RADIX_NULL_LINK) #define IsNull(pos) (((RMF_unit*)tbl->table)[(pos) >> UNIT_BITS].links[(pos) & UNIT_MASK] == RADIX_NULL_LINK)
BYTE* RMF_structuredAsOutputBuffer(FL2_matchTable* const tbl, size_t const index) BYTE* RMF_structuredAsOutputBuffer(FL2_matchTable* const tbl, size_t const pos)
{ {
return (BYTE*)((RMF_unit*)tbl->table + (index >> UNIT_BITS) + ((index & UNIT_MASK) != 0)); return (BYTE*)((RMF_unit*)tbl->table + (pos >> UNIT_BITS) + ((pos & UNIT_MASK) != 0));
} }
/* Restrict the match lengths so that they don't reach beyond index */ /* Restrict the match lengths so that they don't reach beyond pos */
void RMF_structuredLimitLengths(FL2_matchTable* const tbl, size_t const index) void RMF_structuredLimitLengths(FL2_matchTable* const tbl, size_t const pos)
{ {
DEBUGLOG(5, "RMF_limitLengths : end %u, max length %u", (U32)index, RADIX_MAX_LENGTH); DEBUGLOG(5, "RMF_limitLengths : end %u, max length %u", (U32)pos, RADIX_MAX_LENGTH);
SetNull(index - 1); SetNull(pos - 1);
for (size_t length = 2; length < RADIX_MAX_LENGTH && length <= index; ++length) { for (size_t length = 2; length < RADIX_MAX_LENGTH && length <= pos; ++length) {
size_t const i = (index - length) >> UNIT_BITS; size_t const i = (pos - length) >> UNIT_BITS;
size_t const u = (index - length) & UNIT_MASK; size_t const u = (pos - length) & UNIT_MASK;
if (((RMF_unit*)tbl->table)[i].links[u] != RADIX_NULL_LINK) { if (((RMF_unit*)tbl->table)[i].links[u] != RADIX_NULL_LINK) {
((RMF_unit*)tbl->table)[i].lengths[u] = MIN((BYTE)length, ((RMF_unit*)tbl->table)[i].lengths[u]); ((RMF_unit*)tbl->table)[i].lengths[u] = MIN((BYTE)length, ((RMF_unit*)tbl->table)[i].lengths[u]);
} }

View File

@@ -63,12 +63,12 @@ void RC_printPriceTable()
memset(table0, 0, sizeof(table0)); memset(table0, 0, sizeof(table0));
memset(table1, 0, sizeof(table1)); memset(table1, 0, sizeof(table1));
memset(count, 0, sizeof(count)); memset(count, 0, sizeof(count));
for (Probability i = 31; i <= kBitModelTotal - 31; ++i) { for (LZMA2_prob i = 31; i <= kBitModelTotal - 31; ++i) {
RangeEncoder rc; RC_encoder rc;
RC_reset(&rc); RC_reset(&rc);
RC_setOutputBuffer(&rc, buf); RC_setOutputBuffer(&rc, buf);
for (unsigned j = 0; j < test_size; ++j) { for (unsigned j = 0; j < test_size; ++j) {
Probability prob = i; LZMA2_prob prob = i;
RC_encodeBit0(&rc, &prob); RC_encodeBit0(&rc, &prob);
} }
RC_flush(&rc); RC_flush(&rc);
@@ -76,7 +76,7 @@ void RC_printPriceTable()
RC_reset(&rc); RC_reset(&rc);
RC_setOutputBuffer(&rc, buf); RC_setOutputBuffer(&rc, buf);
for (unsigned j = 0; j < test_size; ++j) { for (unsigned j = 0; j < test_size; ++j) {
Probability prob = i; LZMA2_prob prob = i;
RC_encodeBit1(&rc, &prob); RC_encodeBit1(&rc, &prob);
} }
RC_flush(&rc); RC_flush(&rc);
@@ -104,13 +104,13 @@ void RC_printPriceTable()
#endif #endif
void RC_setOutputBuffer(RangeEncoder* const rc, BYTE *const out_buffer) void RC_setOutputBuffer(RC_encoder* const rc, BYTE *const out_buffer)
{ {
rc->out_buffer = out_buffer; rc->out_buffer = out_buffer;
rc->out_index = 0; rc->out_index = 0;
} }
void RC_reset(RangeEncoder* const rc) void RC_reset(RC_encoder* const rc)
{ {
rc->low = 0; rc->low = 0;
rc->range = (U32)-1; rc->range = (U32)-1;
@@ -120,7 +120,7 @@ void RC_reset(RangeEncoder* const rc)
#ifdef __64BIT__ #ifdef __64BIT__
void FORCE_NOINLINE RC_shiftLow(RangeEncoder* const rc) void FORCE_NOINLINE RC_shiftLow(RC_encoder* const rc)
{ {
U64 low = rc->low; U64 low = rc->low;
rc->low = (U32)(low << 8); rc->low = (U32)(low << 8);
@@ -143,7 +143,7 @@ void FORCE_NOINLINE RC_shiftLow(RangeEncoder* const rc)
#else #else
void FORCE_NOINLINE RC_shiftLow(RangeEncoder* const rc) void FORCE_NOINLINE RC_shiftLow(RC_encoder* const rc)
{ {
U32 low = (U32)rc->low; U32 low = (U32)rc->low;
unsigned high = (unsigned)(rc->low >> 32); unsigned high = (unsigned)(rc->low >> 32);
@@ -165,7 +165,7 @@ void FORCE_NOINLINE RC_shiftLow(RangeEncoder* const rc)
#endif #endif
void RC_encodeBitTree(RangeEncoder* const rc, Probability *const probs, unsigned bit_count, unsigned symbol) void RC_encodeBitTree(RC_encoder* const rc, LZMA2_prob *const probs, unsigned bit_count, unsigned symbol)
{ {
assert(bit_count > 1); assert(bit_count > 1);
--bit_count; --bit_count;
@@ -180,7 +180,7 @@ void RC_encodeBitTree(RangeEncoder* const rc, Probability *const probs, unsigned
} while (bit_count != 0); } while (bit_count != 0);
} }
void RC_encodeBitTreeReverse(RangeEncoder* const rc, Probability *const probs, unsigned bit_count, unsigned symbol) void RC_encodeBitTreeReverse(RC_encoder* const rc, LZMA2_prob *const probs, unsigned bit_count, unsigned symbol)
{ {
assert(bit_count != 0); assert(bit_count != 0);
unsigned bit = symbol & 1; unsigned bit = symbol & 1;
@@ -194,7 +194,7 @@ void RC_encodeBitTreeReverse(RangeEncoder* const rc, Probability *const probs, u
} }
} }
void FORCE_NOINLINE RC_encodeDirect(RangeEncoder* const rc, unsigned value, unsigned bit_count) void FORCE_NOINLINE RC_encodeDirect(RC_encoder* const rc, unsigned value, unsigned bit_count)
{ {
assert(bit_count > 0); assert(bit_count > 0);
do { do {

View File

@@ -16,9 +16,9 @@ extern "C" {
#endif #endif
#ifdef LZMA_ENC_PROB32 #ifdef LZMA_ENC_PROB32
typedef U32 Probability; typedef U32 LZMA2_prob;
#else #else
typedef U16 Probability; typedef U16 LZMA2_prob;
#endif #endif
#define kNumTopBits 24U #define kNumTopBits 24U
@@ -44,27 +44,27 @@ typedef struct
U64 low; U64 low;
U32 range; U32 range;
BYTE cache; BYTE cache;
} RangeEncoder; } RC_encoder;
void RC_reset(RangeEncoder* const rc); void RC_reset(RC_encoder* const rc);
void RC_setOutputBuffer(RangeEncoder* const rc, BYTE *const out_buffer); void RC_setOutputBuffer(RC_encoder* const rc, BYTE *const out_buffer);
void FORCE_NOINLINE RC_shiftLow(RangeEncoder* const rc); void FORCE_NOINLINE RC_shiftLow(RC_encoder* const rc);
void RC_encodeBitTree(RangeEncoder* const rc, Probability *const probs, unsigned bit_count, unsigned symbol); void RC_encodeBitTree(RC_encoder* const rc, LZMA2_prob *const probs, unsigned bit_count, unsigned symbol);
void RC_encodeBitTreeReverse(RangeEncoder* const rc, Probability *const probs, unsigned bit_count, unsigned symbol); void RC_encodeBitTreeReverse(RC_encoder* const rc, LZMA2_prob *const probs, unsigned bit_count, unsigned symbol);
void FORCE_NOINLINE RC_encodeDirect(RangeEncoder* const rc, unsigned value, unsigned bit_count); void FORCE_NOINLINE RC_encodeDirect(RC_encoder* const rc, unsigned value, unsigned bit_count);
HINT_INLINE HINT_INLINE
void RC_encodeBit0(RangeEncoder* const rc, Probability *const rprob) void RC_encodeBit0(RC_encoder* const rc, LZMA2_prob *const rprob)
{ {
unsigned prob = *rprob; unsigned prob = *rprob;
rc->range = (rc->range >> kNumBitModelTotalBits) * prob; rc->range = (rc->range >> kNumBitModelTotalBits) * prob;
prob += (kBitModelTotal - prob) >> kNumMoveBits; prob += (kBitModelTotal - prob) >> kNumMoveBits;
*rprob = (Probability)prob; *rprob = (LZMA2_prob)prob;
if (rc->range < kTopValue) { if (rc->range < kTopValue) {
rc->range <<= 8; rc->range <<= 8;
RC_shiftLow(rc); RC_shiftLow(rc);
@@ -72,14 +72,14 @@ void RC_encodeBit0(RangeEncoder* const rc, Probability *const rprob)
} }
HINT_INLINE HINT_INLINE
void RC_encodeBit1(RangeEncoder* const rc, Probability *const rprob) void RC_encodeBit1(RC_encoder* const rc, LZMA2_prob *const rprob)
{ {
unsigned prob = *rprob; unsigned prob = *rprob;
U32 new_bound = (rc->range >> kNumBitModelTotalBits) * prob; U32 new_bound = (rc->range >> kNumBitModelTotalBits) * prob;
rc->low += new_bound; rc->low += new_bound;
rc->range -= new_bound; rc->range -= new_bound;
prob -= prob >> kNumMoveBits; prob -= prob >> kNumMoveBits;
*rprob = (Probability)prob; *rprob = (LZMA2_prob)prob;
if (rc->range < kTopValue) { if (rc->range < kTopValue) {
rc->range <<= 8; rc->range <<= 8;
RC_shiftLow(rc); RC_shiftLow(rc);
@@ -87,7 +87,7 @@ void RC_encodeBit1(RangeEncoder* const rc, Probability *const rprob)
} }
HINT_INLINE HINT_INLINE
void RC_encodeBit(RangeEncoder* const rc, Probability *const rprob, unsigned const bit) void RC_encodeBit(RC_encoder* const rc, LZMA2_prob *const rprob, unsigned const bit)
{ {
unsigned prob = *rprob; unsigned prob = *rprob;
if (bit != 0) { if (bit != 0) {
@@ -100,7 +100,7 @@ void RC_encodeBit(RangeEncoder* const rc, Probability *const rprob, unsigned con
rc->range = (rc->range >> kNumBitModelTotalBits) * prob; rc->range = (rc->range >> kNumBitModelTotalBits) * prob;
prob += (kBitModelTotal - prob) >> kNumMoveBits; prob += (kBitModelTotal - prob) >> kNumMoveBits;
} }
*rprob = (Probability)prob; *rprob = (LZMA2_prob)prob;
if (rc->range < kTopValue) { if (rc->range < kTopValue) {
rc->range <<= 8; rc->range <<= 8;
RC_shiftLow(rc); RC_shiftLow(rc);
@@ -117,7 +117,7 @@ void RC_encodeBit(RangeEncoder* const rc, Probability *const rprob, unsigned con
#define kMinLitPrice 8U #define kMinLitPrice 8U
HINT_INLINE HINT_INLINE
unsigned RC_getTreePrice(const Probability* const prob_table, unsigned bit_count, size_t symbol) unsigned RC_getTreePrice(const LZMA2_prob* const prob_table, unsigned bit_count, size_t symbol)
{ {
unsigned price = 0; unsigned price = 0;
symbol |= ((size_t)1 << bit_count); symbol |= ((size_t)1 << bit_count);
@@ -132,7 +132,7 @@ unsigned RC_getTreePrice(const Probability* const prob_table, unsigned bit_count
} }
HINT_INLINE HINT_INLINE
unsigned RC_getReverseTreePrice(const Probability* const prob_table, unsigned bit_count, size_t symbol) unsigned RC_getReverseTreePrice(const LZMA2_prob* const prob_table, unsigned bit_count, size_t symbol)
{ {
unsigned prob = prob_table[1]; unsigned prob = prob_table[1];
size_t bit = symbol & 1; size_t bit = symbol & 1;
@@ -149,7 +149,7 @@ unsigned RC_getReverseTreePrice(const Probability* const prob_table, unsigned bi
} }
HINT_INLINE HINT_INLINE
void RC_flush(RangeEncoder* const rc) void RC_flush(RC_encoder* const rc)
{ {
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
RC_shiftLow(rc); RC_shiftLow(rc);