MCPcopy Create free account
hub / github.com/F-Stack/f-stack / HUF_setMaxHeight

Function HUF_setMaxHeight

freebsd/contrib/openzfs/module/zstd/lib/zstd.c:8579–8655  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

8577} nodeElt;
8578
8579static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
8580{
8581 const U32 largestBits = huffNode[lastNonNull].nbBits;
8582 if (largestBits <= maxNbBits) return largestBits; /* early exit : no elt > maxNbBits */
8583
8584 /* there are several too large elements (at least >= 2) */
8585 { int totalCost = 0;
8586 const U32 baseCost = 1 << (largestBits - maxNbBits);
8587 int n = (int)lastNonNull;
8588
8589 while (huffNode[n].nbBits > maxNbBits) {
8590 totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
8591 huffNode[n].nbBits = (BYTE)maxNbBits;
8592 n --;
8593 } /* n stops at huffNode[n].nbBits <= maxNbBits */
8594 while (huffNode[n].nbBits == maxNbBits) n--; /* n end at index of smallest symbol using < maxNbBits */
8595
8596 /* renorm totalCost */
8597 totalCost >>= (largestBits - maxNbBits); /* note : totalCost is necessarily a multiple of baseCost */
8598
8599 /* repay normalized cost */
8600 { U32 const noSymbol = 0xF0F0F0F0;
8601 U32 rankLast[HUF_TABLELOG_MAX+2];
8602
8603 /* Get pos of last (smallest) symbol per rank */
8604 memset(rankLast, 0xF0, sizeof(rankLast));
8605 { U32 currentNbBits = maxNbBits;
8606 int pos;
8607 for (pos=n ; pos >= 0; pos--) {
8608 if (huffNode[pos].nbBits >= currentNbBits) continue;
8609 currentNbBits = huffNode[pos].nbBits; /* < maxNbBits */
8610 rankLast[maxNbBits-currentNbBits] = (U32)pos;
8611 } }
8612
8613 while (totalCost > 0) {
8614 U32 nBitsToDecrease = BIT_highbit32((U32)totalCost) + 1;
8615 for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
8616 U32 const highPos = rankLast[nBitsToDecrease];
8617 U32 const lowPos = rankLast[nBitsToDecrease-1];
8618 if (highPos == noSymbol) continue;
8619 if (lowPos == noSymbol) break;
8620 { U32 const highTotal = huffNode[highPos].count;
8621 U32 const lowTotal = 2 * huffNode[lowPos].count;
8622 if (highTotal <= lowTotal) break;
8623 } }
8624 /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
8625 /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
8626 while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))
8627 nBitsToDecrease ++;
8628 totalCost -= 1 << (nBitsToDecrease-1);
8629 if (rankLast[nBitsToDecrease-1] == noSymbol)
8630 rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; /* this rank is no longer empty */
8631 huffNode[rankLast[nBitsToDecrease]].nbBits ++;
8632 if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */
8633 rankLast[nBitsToDecrease] = noSymbol;
8634 else {
8635 rankLast[nBitsToDecrease]--;
8636 if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease)

Callers 1

HUF_buildCTable_wkspFunction · 0.70

Calls 2

memsetFunction · 0.85
BIT_highbit32Function · 0.70

Tested by

no test coverage detected