Exemplo n.º 1
0
        /*! ZSTD_ldm_reduceTable() :
         *  reduce table indexes by `reducerValue` */
        private static void ZSTD_ldm_reduceTable(ldmEntry_t *table, uint size, uint reducerValue)
        {
            uint u;

            for (u = 0; u < size; u++)
            {
                if (table[u].offset < reducerValue)
                {
                    table[u].offset = 0;
                }
                else
                {
                    table[u].offset -= reducerValue;
                }
            }
        }
Exemplo n.º 2
0
        private static nuint ZSTD_ldm_generateSequences_internal(ldmState_t *ldmState, rawSeqStore_t *rawSeqStore, ldmParams_t * @params, void *src, nuint srcSize)
        {
            int    extDict        = (int)(ZSTD_window_hasExtDict(ldmState->window));
            uint   minMatchLength = @params->minMatchLength;
            uint   entsPerBucket  = 1U << (int)@params->bucketSizeLog;
            uint   hBits          = @params->hashLog - @params->bucketSizeLog;
            uint   dictLimit      = ldmState->window.dictLimit;
            uint   lowestIndex    = extDict != 0 ? ldmState->window.lowLimit : dictLimit;
            byte * @base          = ldmState->window.@base;
            byte * dictBase       = extDict != 0 ? ldmState->window.dictBase : null;
            byte * dictStart      = extDict != 0 ? dictBase + lowestIndex : null;
            byte * dictEnd        = extDict != 0 ? dictBase + dictLimit : null;
            byte * lowPrefixPtr   = @base + dictLimit;
            byte * istart         = (byte *)(src);
            byte * iend           = istart + srcSize;
            byte * ilimit         = iend - 8;
            byte * anchor         = istart;
            byte * ip             = istart;
            ldmRollingHashState_t hashState;
            nuint *splits = (nuint *)ldmState->splitIndices;
            ldmMatchCandidate_t *candidates = (ldmMatchCandidate_t *)ldmState->matchCandidates;
            uint numSplits;

            if (srcSize < minMatchLength)
            {
                return((nuint)(iend - anchor));
            }

            ZSTD_ldm_gear_init(&hashState, @params);

            {
                nuint n = 0;

                while (n < minMatchLength)
                {
                    numSplits = 0;
                    n        += ZSTD_ldm_gear_feed(&hashState, ip + n, minMatchLength - n, splits, &numSplits);
                }

                ip += minMatchLength;
            }

            while (ip < ilimit)
            {
                nuint hashed;
                uint  n;

                numSplits = 0;
                hashed    = ZSTD_ldm_gear_feed(&hashState, ip, (nuint)(ilimit - ip), splits, &numSplits);
                for (n = 0; n < numSplits; n++)
                {
                    byte *split  = ip + splits[n] - minMatchLength;
                    ulong xxhash = XXH64((void *)split, minMatchLength, 0);
                    uint  hash   = (uint)(xxhash & (((uint)(1) << (int)hBits) - 1));

                    candidates[n].split    = split;
                    candidates[n].hash     = hash;
                    candidates[n].checksum = (uint)(xxhash >> 32);
                    candidates[n].bucket   = ZSTD_ldm_getBucket(ldmState, hash, *@params);
                    Prefetch0((void *)(candidates[n].bucket));
                }

                for (n = 0; n < numSplits; n++)
                {
                    nuint       forwardMatchLength = 0, backwardMatchLength = 0, bestMatchLength = 0, mLength;
                    byte *      split  = candidates[n].split;
                    uint        checksum = candidates[n].checksum;
                    uint        hash   = candidates[n].hash;
                    ldmEntry_t *bucket = candidates[n].bucket;
                    ldmEntry_t *cur;
                    ldmEntry_t *bestEntry = (ldmEntry_t *)null;
                    ldmEntry_t  newEntry;

                    newEntry.offset   = (uint)(split - @base);
                    newEntry.checksum = checksum;
                    if (split < anchor)
                    {
                        ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *@params);
                        continue;
                    }

                    for (cur = bucket; cur < bucket + entsPerBucket; cur++)
                    {
                        nuint curForwardMatchLength, curBackwardMatchLength, curTotalMatchLength;

                        if (cur->checksum != checksum || cur->offset <= lowestIndex)
                        {
                            continue;
                        }

                        if (extDict != 0)
                        {
                            byte *curMatchBase = cur->offset < dictLimit ? dictBase : @base;
                            byte *pMatch       = curMatchBase + cur->offset;
                            byte *matchEnd     = cur->offset < dictLimit ? dictEnd : iend;
                            byte *lowMatchPtr  = cur->offset < dictLimit ? dictStart : lowPrefixPtr;

                            curForwardMatchLength = ZSTD_count_2segments(split, pMatch, iend, matchEnd, lowPrefixPtr);
                            if (curForwardMatchLength < minMatchLength)
                            {
                                continue;
                            }

                            curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch_2segments(split, anchor, pMatch, lowMatchPtr, dictStart, dictEnd);
                        }
                        else
                        {
                            byte *pMatch = @base + cur->offset;

                            curForwardMatchLength = ZSTD_count(split, pMatch, iend);
                            if (curForwardMatchLength < minMatchLength)
                            {
                                continue;
                            }

                            curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch(split, anchor, pMatch, lowPrefixPtr);
                        }

                        curTotalMatchLength = curForwardMatchLength + curBackwardMatchLength;
                        if (curTotalMatchLength > bestMatchLength)
                        {
                            bestMatchLength     = curTotalMatchLength;
                            forwardMatchLength  = curForwardMatchLength;
                            backwardMatchLength = curBackwardMatchLength;
                            bestEntry           = cur;
                        }
                    }

                    if (bestEntry == null)
                    {
                        ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *@params);
                        continue;
                    }

                    mLength = forwardMatchLength + backwardMatchLength;

                    {
                        uint    offset = (uint)(split - @base) - bestEntry->offset;
                        rawSeq *seq    = rawSeqStore->seq + rawSeqStore->size;

                        if (rawSeqStore->size == rawSeqStore->capacity)
                        {
                            return(unchecked ((nuint)(-(int)ZSTD_ErrorCode.ZSTD_error_dstSize_tooSmall)));
                        }

                        seq->litLength   = (uint)(split - backwardMatchLength - anchor);
                        seq->matchLength = (uint)(mLength);
                        seq->offset      = offset;
                        rawSeqStore->size++;
                    }

                    ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *@params);
                    anchor = split + forwardMatchLength;
                }

                ip += hashed;
            }

            return((nuint)(iend - anchor));
        }