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"); }
public void SetSensitiveInputCells(CellCacheEntry[] sensitiveInputCells) { // need To tell all cells that were previously used, but no longer are, // that they are not consumed by this cell any more ChangeConsumingCells(sensitiveInputCells == null ? CellCacheEntry.EMPTY_ARRAY : sensitiveInputCells); _sensitiveInputCells = sensitiveInputCells; }
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); }
/** * @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; }
/** * @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); }
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); } }
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); } }
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); } } }
/** * 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); }
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); } } }
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++; } }
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++; } }
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; }
public void UpdateFormulaResult(ValueEval result, CellCacheEntry[] sensitiveInputCells, FormulaUsedBlankCellSet usedBlankAreas) { UpdateValue(result); SetSensitiveInputCells(sensitiveInputCells); _usedBlankCellGroup = usedBlankAreas; }
/** * @param inputCell a cell directly used by the formula of this evaluation frame */ public void AddSensitiveInputCell(CellCacheEntry inputCell) { _sensitiveInputCells.Add(inputCell); }
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"); }
/** * Notifies this evaluation tracker that the evaluation of the specified cell is complete. <p/> * * Every successful call To <tt>startEvaluate</tt> must be followed by a call To <tt>endEvaluate</tt> (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); }
/** * @param inputCell a cell directly used by the formula of this evaluation frame */ public void AddSensitiveInputCell(CellCacheEntry inputCell) { _sensitiveInputCells.Add(inputCell); }