private DataBlock GrowCapacity(TKey key, DataBlock block) { try { // TODO review: do we want buffers in LOH or not? <= vs < // next increment will be 64kb, avoid buffer in LOH if (block.RowIndex.Length < MaxBufferLength) { if (block.IncreaseSeriesCapacity <TKey, TValue>() < 0) { return(null); } } else { // refactor switching to source logic to reuse in MutableSeries if (DataSource == null) { DataSource = new DataBlockSource <TKey>(); DataSource.AddLast(block.RowIndex.DangerousGetRef <TKey>(0), block); DataBlock = null; } var minCapacity = block.RowIndex.Length; var newBlock = DataBlock.Create(); if (newBlock.IncreaseSeriesCapacity <TKey, TValue>(minCapacity) < 0) { return(null); } DataSource.AddLast(key, newBlock); block = newBlock; } return(block); } catch (Exception ex) { Trace.TraceError(ex.ToString()); return(null); } }
private bool TryAppendGrowCapacity(TKey key, TValue value, [NotNullWhen(true)] ref DataBlock?block, out object?data) { ThrowHelper.DebugAssert(block != null); data = null; try { if (block == DataBlock.Empty) { block = DataBlock.SeriesCreate(rowLength: 0); data = block; } // TODO review: do we want buffers in LOH or not? <= vs < // next increment will be 64kb, avoid buffer in LOH // ReSharper disable once PossibleNullReferenceException if (block.RowCapacity < MaxBlockRowCount) { if (block.SeriesIncreaseCapacity <TKey, TValue>() < 0) { block = null; return(false); } // WindowOptions?.OnBeforeAppend(); block.SeriesAppend(key, value); } else { // refactor switching to source logic to reuse in MutableSeries if (IsDataBlock(out var db, out var ds)) { Debug.Assert(ReferenceEquals(block, db)); ds = new DataBlockSource <TKey>(); ds.AddLast(block.DangerousRowKey <TKey>(0), block); data = ds; } // before creating a new block try to remove first blocks that // are not used and satisfy MovingWindowOptions //if (!IsDataBlock(out _, out _)) // WindowOptions?.OnBeforeNewBlock(); var minCapacity = block.RowCapacity; var newBlock = DataBlock.SeriesCreate(rowLength: 0); if (newBlock.SeriesIncreaseCapacity <TKey, TValue>(minCapacity) < 0) { block = null; return(false); } // WindowOptions?.OnBeforeAppend(); newBlock.SeriesAppend(key, value); ds.AddLast(key, newBlock); block = newBlock; ThrowHelper.DebugAssert(Data == ds || data == ds); } return(true); } catch (Exception ex) { Trace.TraceError(ex.ToString()); block = null; return(false); } }