private static void ZDICT_insertSortCount(offsetCount_t *table, uint val, uint count) { uint u; table[3].offset = val; table[3].count = count; for (u = 3; u > 0; u--) { offsetCount_t tmp; if (table[u - 1].count >= table[u].count) { break; } tmp = table[u - 1]; table[u - 1] = table[u]; table[u] = tmp; } }
private static nuint ZDICT_analyzeEntropy(void *dstBuffer, nuint maxDstSize, int compressionLevel, void *srcBuffer, nuint *fileSizes, uint nbFiles, void *dictBuffer, nuint dictBufferSize, uint notificationLevel) { uint * countLit = stackalloc uint[256]; HUF_CElt_s * hufTable = stackalloc HUF_CElt_s[256]; uint * offcodeCount = stackalloc uint[31]; short * offcodeNCount = stackalloc short[31]; uint offcodeMax = ZSTD_highbit32((uint)(dictBufferSize + (uint)(128 * (1 << 10)))); uint * matchLengthCount = stackalloc uint[53]; short * matchLengthNCount = stackalloc short[53]; uint * litLengthCount = stackalloc uint[36]; short * litLengthNCount = stackalloc short[36]; uint * repOffset = stackalloc uint[1024]; offsetCount_t *bestRepOffset = stackalloc offsetCount_t[4]; EStats_ress_t esr = new EStats_ress_t { dict = null, zc = null, workPlace = null, }; ZSTD_parameters @params; uint u, huffLog = 11, Offlog = 8, mlLog = 9, llLog = 9, total; nuint pos = 0, errorCode; nuint eSize = 0; nuint totalSrcSize = ZDICT_totalSampleSize(fileSizes, nbFiles); nuint averageSampleSize = totalSrcSize / (nbFiles + (uint)(nbFiles == 0 ? 1 : 0)); byte * dstPtr = (byte *)(dstBuffer); if (offcodeMax > 30) { eSize = (unchecked ((nuint)(-(int)ZSTD_ErrorCode.ZSTD_error_dictionaryCreation_failed))); goto _cleanup; } for (u = 0; u < 256; u++) { countLit[u] = 1; } for (u = 0; u <= offcodeMax; u++) { offcodeCount[u] = 1; } for (u = 0; u <= 52; u++) { matchLengthCount[u] = 1; } for (u = 0; u <= 35; u++) { litLengthCount[u] = 1; } memset((void *)repOffset, 0, (nuint)(sizeof(uint) * 1024)); repOffset[1] = repOffset[4] = repOffset[8] = 1; memset((void *)bestRepOffset, 0, (nuint)(sizeof(offsetCount_t) * 4)); if (compressionLevel == 0) { compressionLevel = 3; } @params = ZSTD_getParams(compressionLevel, (ulong)averageSampleSize, dictBufferSize); esr.dict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, ZSTD_dictLoadMethod_e.ZSTD_dlm_byRef, ZSTD_dictContentType_e.ZSTD_dct_rawContent, @params.cParams, ZSTD_defaultCMem); esr.zc = ZSTD_createCCtx(); esr.workPlace = malloc((nuint)((1 << 17))); if (esr.dict == null || esr.zc == null || esr.workPlace == null) { eSize = (unchecked ((nuint)(-(int)ZSTD_ErrorCode.ZSTD_error_memory_allocation))); goto _cleanup; } for (u = 0; u < nbFiles; u++) { ZDICT_countEStats(esr, &@params, (uint *)countLit, (uint *)offcodeCount, (uint *)matchLengthCount, (uint *)litLengthCount, (uint *)repOffset, (void *)((sbyte *)(srcBuffer) + pos), fileSizes[u], notificationLevel); pos += fileSizes[u]; } { nuint maxNbBits = HUF_buildCTable((HUF_CElt_s *)hufTable, (uint *)countLit, 255, huffLog); if ((ERR_isError(maxNbBits)) != 0) { eSize = maxNbBits; goto _cleanup; } if (maxNbBits == 8) { ZDICT_flatLit((uint *)countLit); maxNbBits = HUF_buildCTable((HUF_CElt_s *)hufTable, (uint *)countLit, 255, huffLog); assert(maxNbBits == 9); } huffLog = (uint)(maxNbBits); } { uint offset; for (offset = 1; offset < 1024; offset++) { ZDICT_insertSortCount(bestRepOffset, offset, repOffset[offset]); } } total = 0; for (u = 0; u <= offcodeMax; u++) { total += offcodeCount[u]; } errorCode = FSE_normalizeCount((short *)offcodeNCount, Offlog, (uint *)offcodeCount, total, offcodeMax, 1); if ((ERR_isError(errorCode)) != 0) { eSize = errorCode; goto _cleanup; } Offlog = (uint)(errorCode); total = 0; for (u = 0; u <= 52; u++) { total += matchLengthCount[u]; } errorCode = FSE_normalizeCount((short *)matchLengthNCount, mlLog, (uint *)matchLengthCount, total, 52, 1); if ((ERR_isError(errorCode)) != 0) { eSize = errorCode; goto _cleanup; } mlLog = (uint)(errorCode); total = 0; for (u = 0; u <= 35; u++) { total += litLengthCount[u]; } errorCode = FSE_normalizeCount((short *)litLengthNCount, llLog, (uint *)litLengthCount, total, 35, 1); if ((ERR_isError(errorCode)) != 0) { eSize = errorCode; goto _cleanup; } llLog = (uint)(errorCode); { nuint hhSize = HUF_writeCTable((void *)dstPtr, maxDstSize, (HUF_CElt_s *)hufTable, 255, huffLog); if ((ERR_isError(hhSize)) != 0) { eSize = hhSize; goto _cleanup; } dstPtr += hhSize; maxDstSize -= hhSize; eSize += hhSize; } { nuint ohSize = FSE_writeNCount((void *)dstPtr, maxDstSize, (short *)offcodeNCount, 30, Offlog); if ((ERR_isError(ohSize)) != 0) { eSize = ohSize; goto _cleanup; } dstPtr += ohSize; maxDstSize -= ohSize; eSize += ohSize; } { nuint mhSize = FSE_writeNCount((void *)dstPtr, maxDstSize, (short *)matchLengthNCount, 52, mlLog); if ((ERR_isError(mhSize)) != 0) { eSize = mhSize; goto _cleanup; } dstPtr += mhSize; maxDstSize -= mhSize; eSize += mhSize; } { nuint lhSize = FSE_writeNCount((void *)dstPtr, maxDstSize, (short *)litLengthNCount, 35, llLog); if ((ERR_isError(lhSize)) != 0) { eSize = lhSize; goto _cleanup; } dstPtr += lhSize; maxDstSize -= lhSize; eSize += lhSize; } if (maxDstSize < 12) { eSize = (unchecked ((nuint)(-(int)ZSTD_ErrorCode.ZSTD_error_dstSize_tooSmall))); goto _cleanup; } MEM_writeLE32((void *)(dstPtr + 0), repStartValue[0]); MEM_writeLE32((void *)(dstPtr + 4), repStartValue[1]); MEM_writeLE32((void *)(dstPtr + 8), repStartValue[2]); eSize += 12; _cleanup: ZSTD_freeCDict(esr.dict); ZSTD_freeCCtx(esr.zc); free(esr.workPlace); return(eSize); }