public override void Evaluate(Evaluation e, long routeKey, bool MultiThread = true) { ExecutingEvaluations++; try { if (e is null) { throw new ArgumentNullException(nameof(e)); } string FilePath = DiskNode._backingStream.FilePath; object streamLock = new object(); using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.RandomAccess)) { List <INodeBlock> matchingNodes = new List <INodeBlock>(LastMatchAmount); for (int header = 0; header < next.Length; header++) { int value = e.DataRow[header]; if (next[header].Length > value) { matchingNodes.AddRange(next[header][value]); } } LastMatchAmount = Math.Max(LastMatchAmount, matchingNodes.Count); void Evaluate(INodeBlock n) { if (n is DiskNode dn) { dn.Evaluate(e, 0, MultiThread); } else if (n is NodeBlock nb) { long bLength = n.NextOffset - n.Offset; if (!ArrayPool.TryDequeue(out byte[] backingData) || backingData.Length < bLength) { backingData = new byte[bLength]; } ByteCache cachedBytes = CachedBytes[nb.Index]; if (cachedBytes.Data is null) { cachedBytes = new ByteCache() { Data = new byte[bLength] }; lock (streamLock) { fs.Seek(n.Offset, SeekOrigin.Begin); fs.Read(cachedBytes.Data, 0, (int)bLength); } CachedBytes[nb.Index] = cachedBytes; } cachedBytes.SetLast(); cachedBytes.Data.CopyTo(backingData, 0); DiskNode nn = new DiskNode(backingData, n.Offset, n.Offset); nn.Evaluate(e, 0, MultiThread); } } if (MultiThread) { Parallel.ForEach(matchingNodes, Evaluate); } else { foreach (INodeBlock nb in matchingNodes) { Evaluate(nb); } } } } finally { ExecutingEvaluations--; FlushMemory(); } }
public void Evaluate(Evaluation e, bool MultiThread = true) => this.Evaluate(e, 0, MultiThread);