Пример #1
0
            public override void Load(CacheNode <TKey, TValue>[] nodes)
            {
                _nodes    = nodes;
                _actNodes = nodes.Length;
                _ranges   = new long[nodes.Length, nodes.Length];
                float sum = 0;

                for (int i = 0; i < nodes.Length; i++)//приводим усредненные частоты к вероятностям
                {
                    var node = nodes[i];
                    var prob = node.GetProbability();
                    sum          += prob;
                    _ranges[i, i] =
                        new RangeDesc
                    {
                        Range = prob,
                        Root  = i
                    };
                }
                for (int i = 0; i < nodes.Length; i++) //приводим усредненные частоты к вероятностям
                {
                    var r = (RangeDesc)_ranges[i, i];
                    r.Range      /= sum;
                    _ranges[i, i] = r;
                }
            }
Пример #2
0
            private unsafe void RebalanceStep(int start, int diff)
            {
                var   ranges        = _uRanges;
                int   end           = start + diff;// *(float*)& - вытаскивает поле Range из записи
                float levelShiftSum = *(float *)&ranges[start * _actNodes + start]
                                      + *(float *)&ranges[end * _actNodes + end];
                float minRange;
                int   minRoot;

                var onlyRightBestTime = *(float *)&ranges[(start + 1) * _actNodes + end];
                var onlyLeftBestTime  = *(float *)&ranges[start * _actNodes + end - 1];

                if (onlyRightBestTime > onlyLeftBestTime)
                {
                    minRange = onlyLeftBestTime;
                    minRoot  = end;
                }
                else
                {
                    minRange = onlyRightBestTime;
                    minRoot  = start;
                }

                /* нижеследующий код является оптимизированной в плане вычислений версией данного
                 * for (var possRoot = start + 1; possRoot < end; possRoot++)
                 * {
                 *  var leftSubTreeBestTime =
                 *(float*)&ranges[start * _actNodes + possRoot - 1];
                 *       //от start*_actNodes+start, до start*_actNodes+end-1, шаг +1
                 *  var rightSubTreeBestTime =
                 *(float*)&ranges[(possRoot + 1) * _actNodes + end];
                 *       //от (start+2)*_actNodes+end, до (end+1)*_actNodes+end,шаг +_actNodes
                 *  var newPossBestTime = leftSubTreeBestTime + rightSubTreeBestTime;
                 *
                 *  if (minRange > newPossBestTime)
                 *  {
                 *      minRange = newPossBestTime;
                 *      minRoot = possRoot;
                 *  }
                 *  levelShiftSum +=
                 *(float*)&ranges[possRoot * _actNodes + possRoot];
                 *        //от (start+1)*_actNodes+start+1, до end*_actNodes+end, шаг +_actNodes+1
                 * }*/

                int leftSubTreeShift  = start * _actNodes + start;
                int rightSubTreeShift = (start + 2) * _actNodes + end;
                int resultShift       = (start + 1) * _actNodes + start + 1;

                for (var possRoot = start + 1; possRoot < end; possRoot++)
                {
                    var leftSubTreeBestTime  = *(float *)&ranges[leftSubTreeShift];
                    var rightSubTreeBestTime = *(float *)&ranges[rightSubTreeShift];
                    var newPossBestTime      = leftSubTreeBestTime + rightSubTreeBestTime;
                    if (minRange > newPossBestTime)
                    {
                        minRange = newPossBestTime;
                        minRoot  = possRoot;
                    }
                    levelShiftSum     += *(float *)&ranges[resultShift];
                    leftSubTreeShift  += 1;
                    rightSubTreeShift += _actNodes;
                    resultShift       += (_actNodes + 1);
                }

                ranges[start * _actNodes + end] = new RangeDesc
                {
                    Range = levelShiftSum + minRange,
                    Root  = minRoot
                };
            }