]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Additional ratio optimizations
authorDanielle Rozenblit <drozenblit@fb.com>
Fri, 14 Oct 2022 17:37:35 +0000 (10:37 -0700)
committerDanielle Rozenblit <drozenblit@fb.com>
Fri, 14 Oct 2022 17:37:35 +0000 (10:37 -0700)
lib/common/huf.h
lib/compress/huf_compress.c

index 72ffbcdff1842df785e2194aa9df7b4498cebc25..5f33d655019c83059bd64d7d8998cc6cf9dbe392 100644 (file)
@@ -173,7 +173,7 @@ size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
 /* ****************************************
  *  HUF detailed API
  * ****************************************/
-#define HUF_OPTIMAL_DEPTH_THRESHOLD ZSTD_btlazy2
+#define HUF_OPTIMAL_DEPTH_THRESHOLD 1
 typedef enum {
    HUF_depth_fast, /** Use heuristic to find the table depth**/
    HUF_depth_optimal /** Test possible table depths to find the one that produces the smallest header + encoded size**/
@@ -191,6 +191,7 @@ typedef enum {
  *  or to save and regenerate 'CTable' using external methods.
  */
 unsigned HUF_minTableLog(size_t srcSize, unsigned maxSymbolValue);
+unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue);
 unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, void* workSpace, size_t wkspSize, HUF_CElt* table, const unsigned* count, HUF_depth_mode depthMode);
 size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits);   /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */
 size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
index b738abfe1579a4f061c7dcfbd88f939c42371d5d..f2686f210132b6913c897cf617d879d9b147a459 100644 (file)
@@ -1235,12 +1235,23 @@ typedef struct {
 #define SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE 4096
 #define SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO 10  /* Must be >= 2 */
 
+unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue)
+{
+    unsigned cardinality = 0;
+    unsigned i;
+
+    for (i = 0; i < maxSymbolValue + 1; i++) {
+        if (count[i] != 0) cardinality += 1;
+    }
+
+    return cardinality;
+}
+
 unsigned HUF_minTableLog(size_t srcSize, unsigned maxSymbolValue)
 {
     U32 minBitsSrc = ZSTD_highbit32((U32)(srcSize)) + 1;
-    U32 minBitsSymbols = ZSTD_highbit32(maxSymbolValue) + 2;
+    U32 minBitsSymbols = ZSTD_highbit32(maxSymbolValue) + 1;
     U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
-    if (minBits < FSE_MIN_TABLELOG) minBits = FSE_MIN_TABLELOG;
     assert(srcSize > 1); /* Not supported, RLE should be used instead */
     return minBits;
 }
@@ -1255,10 +1266,11 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
         size_t optSize = ((size_t) ~0);
         unsigned huffLog;
         size_t maxBits, hSize, newSize;
+        unsigned cardinality = HUF_cardinality(count, maxSymbolValue);
 
         if (wkspSize < sizeof(HUF_buildCTable_wksp_tables)) return optLog;
 
-        for (huffLog = HUF_minTableLog(srcSize, maxSymbolValue); huffLog <= maxTableLog; huffLog++) {
+        for (huffLog = HUF_minTableLog(srcSize, cardinality); huffLog <= maxTableLog; huffLog++) {
             maxBits = HUF_buildCTable_wksp(table, count,
                                             maxSymbolValue, huffLog,
                                             workSpace, wkspSize);