Пример #1
0
        /// <summary>
        /// Updates the potentual blocks that could replace the current block
        /// </summary>
        /// <param name="value"></param>
        /// <param name="bitDiffDiff"></param>
        private void UpdateReplacingCalculations(ref OfcNumber value, int bitDiffDiff = 0)
        {
            // ReSharper disable once ForCanBeConvertedToForeach
            for (var j = _appendingCalculationSavingGrade + 1; j < _replacingCalculations.Length; j++)
            {
                if (!_replacingCalculations[j].IsValid)
                {
                    continue;
                }

                var replacingCalculation = _replacingCalculations[j];
                var savingGrade          = replacingCalculation.VirtualBlock.GetSavingGrade();
                if (!replacingCalculation.ProcessValue(value, _index))
                {
                    _replacingCalculations[j].IsValid = false;
                    continue;
                }

                if ((replacingCalculation.SavedBits += bitDiffDiff) > 0)
                {
                    _replacingCalculations[j].IsValid = false;

                    _calculations.Clear(); //Todo: not jsut clear, but make a replacingCalc on this replacing calc ...
                    _hasRunningPatternCalculation = false;

                    if (!replacingCalculation.OldConcurrentBlock.IsValid) //Todo: check what this was
                    {
                        ReplaceNewestBlock(BlockCalculation.FromReplacingCalculation(replacingCalculation));
                    }
                    else
                    {
                        _blocks[_blocks.Count - 1] = replacingCalculation.OldConcurrentBlock; // set last block to old, non-overlapping state
                        AddNewBlock(BlockCalculation.FromReplacingCalculation(replacingCalculation));
                    }

                    break;
                }

                var newSavingGrade = replacingCalculation.VirtualBlock.GetSavingGrade();

                if (savingGrade != newSavingGrade)
                {
                    _replacingCalculations[(int)savingGrade].IsValid = false;
                    var overriddenCalc = _replacingCalculations[(int)newSavingGrade];
                    if (overriddenCalc.IsValid && overriddenCalc.SavedBits > replacingCalculation.SavedBits)
                    {
                        continue;
                    }
                }

                if (newSavingGrade <= replacingCalculation.OldConcurrentSavingGrade)
                {
                    replacingCalculation.IsValid = false;
                }

                // replacingCalculations[j].IsValid = false;
                _replacingCalculations[(int)newSavingGrade] = replacingCalculation;
            }
        }
Пример #2
0
        /// <summary>
        /// Replaces the current block with a potentual block
        /// </summary>
        /// <param name="with"></param>
        private void ReplaceNewestBlock(BlockCalculation with)
        {
            _blocks[_blocks.Count - 1]       = with.VirtualBlock;
            _lastStableBlock                 = with.VirtualBlock;
            _appendingCalculation            = with;
            _appendingCalculation.SavedBits  = 0;
            _appendingCalculationSavingGrade = (int)with.VirtualBlock.GetSavingGrade();

            for (var i = 1; i < _replacingCalculations.Length; i++)
            {
                _replacingCalculations[i].IsValid = false;
            }
        }
Пример #3
0
        /// <summary>
        /// Creates a block from a potentual block, and sets it as current block
        /// </summary>
        /// <param name="calc"></param>
        private void AddNewBlock(BlockCalculation calc)
        {
            _lastStableBlock      = calc.VirtualBlock;
            _appendingCalculation = calc;
            _blocks.Add(calc.VirtualBlock);
            _isAppendingCalculationValid     = true;
            _appendingCalculationSavingGrade = (int)calc.VirtualBlock.GetSavingGrade();

            for (var i = 1; i < _replacingCalculations.Length; i++)
            {
                _replacingCalculations[i].IsValid = false;
            }
        }
Пример #4
0
        /// <summary>
        /// Does one step. Will update everything
        /// </summary>
        /// <returns></returns>
        public bool ProcessNextValue()
        {
            var value       = Values[_index];
            var patternPred = _patternPredictor.PredictNext(value);

            #region adding value to last block and updating replacing calculations


            if (_isAppendingCalculationValid)
            {
                var lastBitDiff        = _appendingCalculation.SavedBits;
                var lastAppendingBlock = _appendingCalculation.VirtualBlock;

                if (_appendingCalculation.ProcessValue(value, _index))
                {
                    var bifDiffDiff = lastBitDiff - _appendingCalculation.SavedBits;
                    if (_appendingCalculation.SavedBits > 0)
                    {
                        if (_appendingCalculation.VirtualBlock.Length - _lastStableBlock.Length > 1) // we made a jump, maybe there were some calcs started in the meantime?
                        {
                            TransformCalcsToReplaceCalsOrDelete(lastAppendingBlock, _appendingCalculation.SavedBits);
                        }

                        ReplaceNewestBlock(_appendingCalculation);
                    }

                    _appendingCalculationSavingGrade = (int)_appendingCalculation.VirtualBlock.GetSavingGrade();

                    UpdateReplacingCalculations(ref value, bifDiffDiff);

                    if (patternPred && _appendingCalculationSavingGrade < (int)Block.SavingGrade.Pattern && !_replacingCalculations[(int)Block.SavingGrade.Pattern].IsValid)
                    {
                        var block = new Block(_index, value.Exponent, value.NeededBitsNumber, value.IsNegative, value.Number, this, Methods.PatternSame, true);
                        var calc  = _replacingCalculations[(int)Block.SavingGrade.Pattern];
                        calc.Initialize(-Headers.StandardBlockPatternSame, block, lastAppendingBlock, (Block.SavingGrade)_appendingCalculationSavingGrade);
                        if (calc.ProcessValue(value, _index))
                        {
                            _replacingCalculations[(int)Block.SavingGrade.Pattern] = calc;
                        }
                    }
                }
                else
                {
                    UpdateReplacingCalculations(ref value);
                    _isAppendingCalculationValid = false;
                }
            }
            else
            {
                UpdateReplacingCalculations(ref value);
            }

            #endregion

            #region updating current calculations if nessecary
            var isLastBlockUp2Date = _lastStableBlock.Index + _lastStableBlock.Length - 1 == _index;

            for (var j = 0; j < _calculations.Count; j++)
            {
                var calc = _calculations[j];

                // Todo: we shouldn't only remove calculations that are super far away, we should also remove calculations that have a very negative calc.SavedBits

                var hasPattern = calc.VirtualBlock.HasPattern;
                if (!calc.ProcessValue(value, _index))
                {
                    if (hasPattern)
                    {
                        _hasRunningPatternCalculation = false;
                    }
                    _calculations.RemoveAt(j--); // There was some error / the block is impossible, e.g. the exps are different and you can't even correct the values because of overflows ...
                    continue;
                }

                if (hasPattern && !calc.VirtualBlock.HasPattern)
                {
                    //throw new Exception("c#er is wrong");
                    _hasRunningPatternCalculation = false;
                }

                if (calc.SavedBits > 0)
                {
                    if (calc.VirtualBlock.HasPattern)
                    {
                        _hasRunningPatternCalculation = false;
                    }

                    if (_lastStableBlock.Index + _lastStableBlock.Length - 1 >= calc.VirtualBlock.Index)
                    {
#if debug
                        Console.WriteLine(_debugCounter);
                        _debugSkip    = 0;
                        _debugEnabled = true;
#endif
                        _calculations.RemoveAt(j--);

                        continue;
                        throw new InvalidOperationException("Blocks sharing values! (ノ° ͜ʖ ͡°)ノ︵┻┻ ");
                    }

                    AddNewBlock(calc);

                    isLastBlockUp2Date = true;

                    for (var k = j + 1; k < _calculations.Count; k++) // we need to update the rest here or they jump one update tick if they get transformed to ReplaceCalcs ...
                    {
                        var calc2 = _calculations[k];
                        if (!calc2.ProcessValue(value, _index))
                        {
                            _calculations.RemoveAt(k--);
                            continue;
                        }
                        _calculations[k] = calc2;
                    }

                    TransformCalcsToReplaceCalsOrDelete(Block.InvalidBlock, calc.SavedBits, j); // we give an invalid block because the just created block and the already running calc could never co-exist. The just created block will get deleted if a replacing calc with an invalid oldConcurrentBLock gets founded

                    break;                                                                      // Bug: actually, breaking here is pretty bad. There could be multiple calculations that want to create a block, and maybe this is not the best one. Saves some performance though
                }

                _calculations[j] = calc;
            }

            #endregion

            #region starting new calculations if nessecary

            //if (isLastBlockUp2Date)
            //{
            //    if (patternPred && _appendingCalculationSavingGrade < (int)Block.SavingGrade.Pattern && !_replacingCalculations[(int)Block.SavingGrade.Pattern].IsValid)
            //    {
            //        var block = new Block(_index, value.Exponent, value.NeededBitsNumber, value.IsNegative, value.Number, this, Methods.PatternSame, true);
            //        var calc = _replacingCalculations[(int)Block.SavingGrade.Pattern];
            //        calc.Initialize(-Headers.StandardBlockPatternSame, block, _lastStableBlock, (Block.SavingGrade)_appendingCalculationSavingGrade);
            //        if (calc.ProcessValue(ref value, _index))
            //            _replacingCalculations[(int)Block.SavingGrade.Pattern] = calc;
            //    }
            //}
            //else
            if (!_hasRunningPatternCalculation && !isLastBlockUp2Date)
            {
                if (patternPred)
                {
                    var calc = new BlockCalculation(-Headers.StandardBlockPatternSame, new Block(_index, value.Exponent, 0, false, value.Number, this, Methods.PatternSame, true));
                    if (calc.ProcessValue(value, _index))
                    {
                        _calculations.Add(calc);
                        _hasRunningPatternCalculation = true;
                    }
                }
                else
                {
                    var hasExp = false;
                    foreach (var runningCalculation in _calculations) //Todo: pre calculate that (bool array?)
                    {
                        if (runningCalculation.VirtualBlock.Exponent == value.Exponent)
                        {
                            hasExp = true;
                            break;
                        }
                    }
                    if (!hasExp)
                    {
                        BlockCalculation calc;

                        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression - You can't see **** if you do a ?:
                        if (value.Exponent == 0)
                        {
                            calc = new BlockCalculation(-Headers.StandardBlockNumbersNoExp, new Block(_index, 0, value.NeededBitsNumber, value.IsNegative, value.Number, this, Methods.NumbersNoExp, false));
                        }
                        else
                        {
                            calc = new BlockCalculation(-Headers.StandardBlockFloatSimmilar, new Block(_index, value.Exponent, value.NeededBitsNumber, value.IsNegative, value.Number, this, Methods.FloatSimmilar, false));
                        }

                        if (calc.ProcessValue(value, _index))
                        {
                            _calculations.Add(calc);
                        }
                        else
                        {
                            throw new Exception("Nice blockfinding Kappa");
                        }
                    }
                }
            }
            #endregion

            return(++_index < ValueCount);
        }