Beispiel #1
0
        private void BackwardPass(byte[] input, int startPosition)
        {
            var matches = GetAllMatches(input, startPosition);

            var dataLength = input.Length - startPosition;
            var unitSize   = _finders.Min(x => (int)x.DataType);

            for (var i = dataLength - unitSize; i >= 0; i -= unitSize)
            {
                // First get the compression length when the next byte is not compressed
                _history[i] = new PriceHistoryElement
                {
                    IsLiteral = true,
                    Length    = unitSize,
                    Price     = _priceCalculator.CalculateLiteralPrice(input[i + startPosition])
                };
                if (i + unitSize < dataLength)
                {
                    _history[i].Price += _history[i + unitSize].Price;
                }

                // Then go through all longest matches at position i
                var matchIndex = 0;
                foreach (var match in matches[i])
                {
                    // Get the longest match at position i
                    if (match != null)
                    {
                        var matchLength = match.Length;
                        for (var j = _finders[matchIndex].MinMatchSize; j <= matchLength; j += unitSize)
                        {
                            match.Length = j;
                            var matchPrice = _priceCalculator.CalculateMatchPrice(match);

                            long newCompLen = matchPrice;
                            if (i + j < dataLength)
                            {
                                newCompLen += _history[i + j].Price;
                            }

                            if (newCompLen < _history[i].Price)
                            {
                                _history[i].IsLiteral    = false;
                                _history[i].Displacement = match.Displacement;
                                _history[i].Length       = j;
                                _history[i].Price        = newCompLen;
                            }
                        }
                    }

                    matchIndex++;
                }
            }
        }
Beispiel #2
0
        private void ForwardPass(byte[] input, int startPosition)
        {
            var state = new ParserState(_history, FindOptions);

            var unitSize     = (int)FindOptions.UnitSize;
            var dataPosition = 0;
            var dataLength   = input.Length - startPosition;

            foreach (var matches in GetAllMatches(input, startPosition))
            {
                // Calculate literal place at position
                var literalPrice = _priceCalculator.CalculateLiteralPrice(state, dataPosition, input[dataPosition]);
                literalPrice += _history[dataPosition].Price;
                if (dataPosition + unitSize < _history.Length &&
                    literalPrice < _history[dataPosition + unitSize].Price)
                {
                    _history[dataPosition + unitSize].IsLiteral    = true;
                    _history[dataPosition + unitSize].Price        = literalPrice;
                    _history[dataPosition + unitSize].Length       = unitSize;
                    _history[dataPosition + unitSize].Displacement = 0;
                }

                // Then go through all longest matches at current position
                for (int finderIndex = 0; finderIndex < _finders.Length; finderIndex++)
                {
                    var finderMatches = matches[finderIndex];
                    if (finderMatches == null || !finderMatches.Any())
                    {
                        continue;
                    }

                    var longestMatch = finderMatches.MaxBy(x => x.Position);

                    for (var j = _finders[finderIndex].FindLimitations.MinLength; j <= longestMatch.Length; j += unitSize)
                    {
                        var matchPrice = _priceCalculator.CalculateMatchPrice(state, dataPosition, longestMatch.Displacement, j);
                        matchPrice += _history[dataPosition].Price;

                        if (dataPosition + j < _history.Length &&
                            matchPrice < _history[dataPosition + j].Price)
                        {
                            _history[dataPosition + j].IsLiteral    = false;
                            _history[dataPosition + j].Displacement = longestMatch.Displacement;
                            //finderMatches.TakeWhile(x => x.Length >= j).OrderBy(x => x.Displacement).First().Displacement;
                            _history[dataPosition + j].Length = j;
                            _history[dataPosition + j].Price  = matchPrice;
                        }
                    }
                }

                dataPosition += unitSize;
            }
        }
Beispiel #3
0
        private void ForwardPass(byte[] input, int startPosition, PositionElement[] history)
        {
            var matches = GetAllMatches(input, startPosition);

            var unitSize = (int)FindOptions.UnitSize;

            for (var dataPosition = 0; dataPosition < input.Length - startPosition; dataPosition += unitSize)
            {
                // Calculate literal place at position
                var element           = history[dataPosition];
                var newRunLength      = element.IsMatchRun ? unitSize : element.CurrentRunLength + unitSize;
                var isFirstLiteralRun = IsFirstLiteralRun(dataPosition, unitSize, history);
                var literalPrice      = _priceCalculator.CalculateLiteralPrice(input[dataPosition], newRunLength, isFirstLiteralRun);
                literalPrice += element.Price;

                if (dataPosition + unitSize < history.Length &&
                    literalPrice <= history[dataPosition + unitSize].Price)
                {
                    var nextElement = history[dataPosition + unitSize];

                    nextElement.Parent           = element;
                    nextElement.Price            = literalPrice;
                    nextElement.CurrentRunLength = newRunLength;
                    nextElement.IsMatchRun       = false;
                    nextElement.Match            = null;
                }

                // Then go through all longest matches at current position
                for (var finderIndex = 0; finderIndex < _finders.Length; finderIndex++)
                {
                    var finderMatch = matches[finderIndex][dataPosition];
                    if (finderMatch == null || !finderMatch.HasMatches)
                    {
                        continue;
                    }

                    for (var j = _finders[finderIndex].FindLimitations.MinLength; j <= finderMatch.MaxLength; j += unitSize)
                    {
                        var displacement = finderMatch.GetDisplacement(j);
                        if (displacement < 0)
                        {
                            continue;
                        }

                        newRunLength = element.IsMatchRun ? element.CurrentRunLength + 1 : 1;
                        var matchPrice = _priceCalculator.CalculateMatchPrice(displacement, j, newRunLength, input[dataPosition]);
                        matchPrice += element.Price;

                        if (dataPosition + j < history.Length &&
                            matchPrice < history[dataPosition + j].Price)
                        {
                            var nextElement = history[dataPosition + j];

                            nextElement.Parent           = element;
                            nextElement.Price            = matchPrice;
                            nextElement.CurrentRunLength = newRunLength;
                            nextElement.IsMatchRun       = true;
                            nextElement.Match            = new Match(dataPosition, displacement, j);
                        }
                    }
                }
            }
        }