예제 #1
0
        private static bool AddInternal(CellCacheEntry[] arr, CellCacheEntry cce)
        {
            int startIx = cce.GetHashCode() % arr.Length;

            for (int i = startIx; i < arr.Length; i++)
            {
                CellCacheEntry item = arr[i];
                if (item == cce)
                {
                    // already present
                    return(false);
                }
                if (item == null)
                {
                    arr[i] = cce;
                    return(true);
                }
            }
            for (int i = 0; i < startIx; i++)
            {
                CellCacheEntry item = arr[i];
                if (item == cce)
                {
                    // already present
                    return(false);
                }
                if (item == null)
                {
                    arr[i] = cce;
                    return(true);
                }
            }
            throw new InvalidOperationException("No empty space found");
        }
예제 #2
0
        public bool Remove(CellCacheEntry cce)
        {
            FormulaCellCacheEntry[] arr = _arr;

            if (_size * 3 < _arr.Length && _arr.Length > 8)
            {
                // re-Hash
                bool found = false;
                FormulaCellCacheEntry[] prevArr = _arr;
                FormulaCellCacheEntry[] newArr  = new FormulaCellCacheEntry[_arr.Length / 2]; // shrink 50%
                for (int i = 0; i < prevArr.Length; i++)
                {
                    FormulaCellCacheEntry prevCce = _arr[i];
                    if (prevCce != null)
                    {
                        if (prevCce == cce)
                        {
                            found = true;
                            _size--;
                            // skip it
                            continue;
                        }
                        AddInternal(newArr, prevCce);
                    }
                }
                _arr = newArr;
                return(found);
            }
            // else - usual case
            // delete single element (without re-Hashing)

            int startIx = cce.GetHashCode() % arr.Length;

            // note - can't exit loops upon finding null because of potential previous deletes
            for (int i = startIx; i < arr.Length; i++)
            {
                FormulaCellCacheEntry item = arr[i];
                if (item == cce)
                {
                    // found it
                    arr[i] = null;
                    _size--;
                    return(true);
                }
            }
            for (int i = 0; i < startIx; i++)
            {
                FormulaCellCacheEntry item = arr[i];
                if (item == cce)
                {
                    // found it
                    arr[i] = null;
                    _size--;
                    return(true);
                }
            }
            return(false);
        }
예제 #3
0
        /**
         * @return never <c>null</c>, (possibly empty) array of all cells directly used while
         * evaluating the formula of this frame.
         */
        private CellCacheEntry[] GetSensitiveInputCells()
        {
            int nItems = _sensitiveInputCells.Count;

            if (nItems < 1)
            {
                return(CellCacheEntry.EMPTY_ARRAY);
            }
            CellCacheEntry[] result = new CellCacheEntry[nItems];
            result = (CellCacheEntry[])_sensitiveInputCells.ToArray(typeof(CellCacheEntry));
            return(result);
        }
예제 #4
0
        public void AcceptFormulaDependency(CellCacheEntry cce)
        {
            // Tell the currently evaluating cell frame that it Has a dependency on the specified
            int prevFrameIndex = _evaluationFrames.Count - 1;

            if (prevFrameIndex < 0)
            {
                // Top level frame, there is no 'cell' above this frame that is using the current cell
            }
            else
            {
                CellEvaluationFrame consumingFrame = (CellEvaluationFrame)_evaluationFrames[prevFrameIndex];
                consumingFrame.AddSensitiveInputCell(cce);
            }
        }
예제 #5
0
        private void ChangeConsumingCells(CellCacheEntry[] usedCells)
        {
            CellCacheEntry[] prevUsedCells = _sensitiveInputCells;
            int nUsed = usedCells.Length;

            for (int i = 0; i < nUsed; i++)
            {
                usedCells[i].AddConsumingCell(this);
            }
            if (prevUsedCells == null)
            {
                return;
            }
            int nPrevUsed = prevUsedCells.Length;

            if (nPrevUsed < 1)
            {
                return;
            }
            ArrayList usedSet;

            if (nUsed < 1)
            {
                usedSet = new ArrayList();
            }
            else
            {
                usedSet = new ArrayList(nUsed * 3 / 2);
                for (int i = 0; i < nUsed; i++)
                {
                    usedSet.Add(usedCells[i]);
                }
            }
            for (int i = 0; i < nPrevUsed; i++)
            {
                CellCacheEntry prevUsed = prevUsedCells[i];
                if (!usedSet.Contains(prevUsed))
                {
                    // previously was used by cellLoc, but not anymore
                    prevUsed.ClearConsumingCell(this);
                }
            }
        }
예제 #6
0
        /**
         * Notifies this evaluation tracker that the evaluation of the specified cell is complete. <p/>
         *
         * Every successful call To <c>startEvaluate</c> must be followed by a call To <c>endEvaluate</c> (recommended in a finally block) To enable
         * proper tracking of which cells are being evaluated at any point in time.<p/>
         *
         * Assuming a well behaved client, parameters To this method would not be
         * required. However, they have been included To assert correct behaviour,
         * and form more meaningful error messages.
         */
        public void EndEvaluate(CellCacheEntry cce)
        {
            int nFrames = _evaluationFrames.Count;

            if (nFrames < 1)
            {
                throw new InvalidOperationException("Call To endEvaluate without matching call To startEvaluate");
            }

            nFrames--;
            CellEvaluationFrame frame = (CellEvaluationFrame)_evaluationFrames[nFrames];

            if (cce != frame.GetCCE())
            {
                throw new InvalidOperationException("Wrong cell specified. ");
            }
            // else - no problems so pop current frame
            _evaluationFrames.RemoveAt(nFrames);
            _currentlyEvaluatingCells.Remove(cce);
        }
예제 #7
0
 public void Add(CellCacheEntry cce)
 {
     if (_size * 3 >= _arr.Length * 2)
     {
         // re-Hash
         FormulaCellCacheEntry[] prevArr = _arr;
         FormulaCellCacheEntry[] newArr  = new FormulaCellCacheEntry[4 + _arr.Length * 3 / 2]; // grow 50%
         for (int i = 0; i < prevArr.Length; i++)
         {
             FormulaCellCacheEntry prevCce = _arr[i];
             if (prevCce != null)
             {
                 AddInternal(newArr, prevCce);
             }
         }
         _arr = newArr;
     }
     if (AddInternal(_arr, cce))
     {
         _size++;
     }
 }
예제 #8
0
 /**
  * @param inputCell a cell directly used by the formula of this evaluation frame
  */
 public void AddSensitiveInputCell(CellCacheEntry inputCell)
 {
     _sensitiveInputCells.Add(inputCell);
 }