public void GlobalSetup() { try { var eventsApi = new ApiFacade { ProgressHandler = new ConsoleProgress() }; var filePath = Environment.GetEnvironmentVariable(FilePathEnvVariable); BucketContainer = eventsApi.LoadEventsFromFileAsync(filePath, LoadStrategyType.LoadEventsAndPayloadsForChart) .GetAwaiter() .GetResult(); var lastBucket = BucketContainer.GetLastBucket(); Start = BucketContainer.FirstTimestamp; End = lastBucket?.GetAbsoluteTimeForEvent(lastBucket.GetLastEvent()) ?? 0; } catch (Exception exc) { Console.WriteLine(); Console.WriteLine(exc.ToString()); } }
/// <summary> /// Gets densities for segments with size equal to <paramref name="segmentSize"/> /// </summary> /// <param name="container">Bucket container</param> /// <param name="start">Start time</param> /// <param name="end">End time</param> /// <param name="segmentSize">Length/duration of one segment</param> /// <param name="targetBuffer">Targer buffer into which calculated densities are saved</param> /// <returns></returns> public static Span <double> GetDensities(BucketContainer container, long start, long end, long segmentSize, ref double[] targetBuffer) { if (end <= start) { throw new ArgumentException("Wrong interval. End timestamp must be greater than start timestamp."); } if (end - start < segmentSize) { throw new ArgumentException("Segment size is too big for this time interval", nameof(segmentSize)); } var lastBucket = container.GetLastBucket(); var maxTime = lastBucket.GetAbsoluteTimeForEvent(lastBucket.GetLastEvent()); if (end > maxTime + 1) { end = maxTime + 1; } // Start time is out of range if (end < start) { return(Span <double> .Empty); } ushort totalSegments = GetTotalSegments(start, end, segmentSize); if (targetBuffer == null) { targetBuffer = new double[totalSegments]; } else if (targetBuffer.Length < totalSegments) { throw new ArgumentException("Target buffer is too short", nameof(targetBuffer)); } int processedSegmentsUsingHints = -1; try { checked { container.DensityHintContainer?.TrySetDensitiesUsingHints( start - container.FirstTimestamp, end - container.FirstTimestamp, segmentSize, targetBuffer, out processedSegmentsUsingHints ); } } catch (OverflowException) { throw new InvalidOperationException("Too big range of events"); } #if DEBUG if (processedSegmentsUsingHints == 0 && segmentSize >= 10_000_000) { Debug.Fail("Density calculation is perfoming in unoptimized way. It can be eliminated by adjusting range and segment size to appropriate values."); } #endif if (processedSegmentsUsingHints < 0) { processedSegmentsUsingHints = 0; } if (processedSegmentsUsingHints == totalSegments) { return(targetBuffer.AsSpan(0, totalSegments)); } start += processedSegmentsUsingHints * segmentSize; int uncalculatedDensitiesCount = totalSegments - processedSegmentsUsingHints; var targetBufferCopy = targetBuffer; Parallel.ForEach(GetPartitions(start, segmentSize, targetBuffer.AsSpan(processedSegmentsUsingHints, uncalculatedDensitiesCount)), (partition) => { Span <double> batch = targetBufferCopy.AsSpan(processedSegmentsUsingHints, uncalculatedDensitiesCount) .Slice(partition.leftBoundary, partition.batchLength); DensityCalculator.CalculateDensities( container.Buckets, new DensityCalculationRequest(partition.start, partition.end, segmentSize), batch, true, out long processedRange ); }); return(targetBuffer.AsSpan(0, totalSegments)); }