Beispiel #1
0
        /* ZSTD_ldm_skipRawSeqStoreBytes():
         * Moves forward in rawSeqStore by nbBytes, updating fields 'pos' and 'posInSequence'.
         * Not to be used in conjunction with ZSTD_ldm_skipSequences().
         * Must be called for data with is not passed to ZSTD_ldm_blockCompress().
         */
        public static void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t *rawSeqStore, nuint nbBytes)
        {
            uint currPos = (uint)(rawSeqStore->posInSequence + nbBytes);

            while (currPos != 0 && rawSeqStore->pos < rawSeqStore->size)
            {
                rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];

                if (currPos >= currSeq.litLength + currSeq.matchLength)
                {
                    currPos -= currSeq.litLength + currSeq.matchLength;
                    rawSeqStore->pos++;
                }
                else
                {
                    rawSeqStore->posInSequence = currPos;
                    break;
                }
            }

            if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size)
            {
                rawSeqStore->posInSequence = 0;
            }
        }
Beispiel #2
0
        /**
         * If the sequence length is longer than remaining then the sequence is split
         * between this block and the next.
         *
         * Returns the current sequence to handle, or if the rest of the block should
         * be literals, it returns a sequence with offset == 0.
         */
        private static rawSeq maybeSplitSequence(rawSeqStore_t *rawSeqStore, uint remaining, uint minMatch)
        {
            rawSeq sequence = rawSeqStore->seq[rawSeqStore->pos];

            assert(sequence.offset > 0);
            if (remaining >= sequence.litLength + sequence.matchLength)
            {
                rawSeqStore->pos++;
                return(sequence);
            }

            if (remaining <= sequence.litLength)
            {
                sequence.offset = 0;
            }
            else if (remaining < sequence.litLength + sequence.matchLength)
            {
                sequence.matchLength = remaining - sequence.litLength;
                if (sequence.matchLength < minMatch)
                {
                    sequence.offset = 0;
                }
            }

            ZSTD_ldm_skipSequences(rawSeqStore, remaining, minMatch);
            return(sequence);
        }
Beispiel #3
0
        /**
         * ZSTD_ldm_blockCompress():
         *
         * Compresses a block using the predefined sequences, along with a secondary
         * block compressor. The literals section of every sequence is passed to the
         * secondary block compressor, and those sequences are interspersed with the
         * predefined sequences. Returns the length of the last literals.
         * Updates `rawSeqStore.pos` to indicate how many sequences have been consumed.
         * `rawSeqStore.seq` may also be updated to split the last sequence between two
         * blocks.
         * @return The length of the last literals.
         *
         * NOTE: The source must be at most the maximum block size, but the predefined
         * sequences can be any size, and may be longer than the block. In the case that
         * they are longer than the block, the last sequences may need to be split into
         * two. We handle that case correctly, and update `rawSeqStore` appropriately.
         * NOTE: This function does not return any errors.
         */
        public static nuint ZSTD_ldm_blockCompress(rawSeqStore_t *rawSeqStore, ZSTD_matchState_t *ms, seqStore_t *seqStore, uint *rep, void *src, nuint srcSize)
        {
            ZSTD_compressionParameters *cParams = &ms->cParams;
            uint minMatch = cParams->minMatch;
            ZSTD_blockCompressor blockCompressor = ZSTD_selectBlockCompressor(cParams->strategy, ZSTD_matchState_dictMode(ms));
            byte *istart = (byte *)(src);
            byte *iend   = istart + srcSize;
            byte *ip     = istart;

            if (cParams->strategy >= ZSTD_strategy.ZSTD_btopt)
            {
                nuint lastLLSize;

                ms->ldmSeqStore = rawSeqStore;
                lastLLSize      = blockCompressor(ms, seqStore, rep, src, srcSize);
                ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore, srcSize);
                return(lastLLSize);
            }

            assert(rawSeqStore->pos <= rawSeqStore->size);
            assert(rawSeqStore->size <= rawSeqStore->capacity);
            while (rawSeqStore->pos < rawSeqStore->size && ip < iend)
            {
                rawSeq sequence = maybeSplitSequence(rawSeqStore, (uint)(iend - ip), minMatch);
                int    i;

                if (sequence.offset == 0)
                {
                    break;
                }

                assert(ip + sequence.litLength + sequence.matchLength <= iend);
                ZSTD_ldm_limitTableUpdate(ms, ip);
                ZSTD_ldm_fillFastTables(ms, (void *)ip);

                {
                    nuint newLitLength = blockCompressor(ms, seqStore, rep, (void *)ip, sequence.litLength);

                    ip += sequence.litLength;
                    for (i = 3 - 1; i > 0; i--)
                    {
                        rep[i] = rep[i - 1];
                    }

                    rep[0] = sequence.offset;
                    ZSTD_storeSeq(seqStore, newLitLength, ip - newLitLength, iend, sequence.offset + (uint)((3 - 1)), sequence.matchLength - 3);
                    ip += sequence.matchLength;
                }
            }

            ZSTD_ldm_limitTableUpdate(ms, ip);
            ZSTD_ldm_fillFastTables(ms, (void *)ip);
            return(blockCompressor(ms, seqStore, rep, (void *)ip, (nuint)(iend - ip)));
        }