public/Message/Measure-Frequency.ps1

using module '..\..\modules\Enums.psm1'
using module '..\..\modules\Helper\DateTimeHelper.psm1'
using module '..\..\modules\Helper\StringHelper.psm1'
using module '..\..\modules\Helper\ObjectHelper.psm1'
using module '..\..\modules\Session.psd1'
using module '..\..\modules\FeedProcessor\ProcessorBase.psm1'
using module '..\..\modules\FeedProcessor\Auditlog\Message.psm1'

function Measure-Frequency{
    [CmdletBinding()]
    [Alias('msc')]
    param(
        [Parameter(ValueFromPipeline=$true, Mandatory=$true)]
        [Message] $message,
        [int]$displayAbove,
        [switch] $summary,
        [int32] $intervalBlock = 100,
        [int32] $percentageThreshold = 5
    )

    BEGIN {
        [hashtable] $frequency = @{}
        $count = 0; $previousBlock = 1
        $maxFrequency = 0; $maxKey = $null
        $processor = $null

        try {
            $maxBlocks = [int32](10000/$intervalBlock)
        }
        catch {
            $maxBlocks = 200
        }
        $threshold = @()
        for ($i=0; $i -le $maxBlocks; $i++) { $threshold += 0 }
    }
    PROCESS {
        $count++

        if ($null -eq $processor) { $processor = [ProcessorFactory]::getBySource($message.source) }
        $processor.message = $message
        $processor.ProcessMarket($message.line, [SEARCH_SCOPE]::internalId, '*', '*')

        foreach ($market in $processor.message.event.markets) {
            $key = $market.ident()
            if (-not $frequency.ContainsKey($key)){
                $frequency.Add($key, 1)
            }
            else {
                $frequency[$key] += 1
            }

            if ($frequency[$key] -gt $maxFrequency){
                $maxKey = $key
                $maxFrequency = $frequency[$key]
            }
        }
    }
    END {
        if ($frequency.Count -gt 0){
            if ($summary){

                $allFrequencies = @()
                foreach ($item in $frequency.Values){
                    $allFrequencies += $item
                    $i = ([Math]::floor($item/$intervalBlock))
                    $threshold[[Math]::min($i, $maxBlocks)] += 1
                }

                Write-Output "Summary of total $($frequency.Count) analyzed markets:"
                $percentile = [Config]::Load().percentile

                Write-Debug ('Interval block: {0}, threshold: {1}, percentile: {2}' -f @($intervalBlock, $percentageThreshold, $percentile))
                Write-Output ([StringHelper]::groupValueByBlocks($threshold, $intervalBlock, $percentageThreshold, $percentile, $false))

                $sorted = ($allFrequencies | Sort-Object )

                $printLines = [ordered]@{}
                foreach ($i in $percentile) {
                    $array = $sorted | Select-Object -First $([Math]::Floor($i * $frequency.Count))

                    $average = ($array | Measure-Object -Average).Average
                    $median = [StringHelper]::getMedian($array)

                    $line = @(("{0}th" -f ($i * 100)), $sorted[$([Math]::Floor($i * $analyzedLines - 1))], `
                        ("{0:N0}" -f $average), ("{0:N0}" -f $median))
                    $printLines.Add($i, $line)
                }

                Write-Table -title 'Percentile analysis:' -columns @('percentile', 'frequency', 'average', 'median') -values $printLines
            }
            else {
                $count=0
                foreach($item in ($frequency.GetEnumerator() | Where-Object { $_.Value -ge $displayAbove } | Sort-Object Value -Desc )){
                    $count++
                    $temp = [Market]::reverseIdent($item.Key)

                    Write-Output ([PSCustomObject]@{PSTypeName='MarketFrequency'; marketId=$temp[0]; `
                        specifiers=$temp[1]; frequency=$item.Value})
                }

                Write-Output ("Total {0} out of {1} ({2:P1}) were processed above {3}." `
                    -f @($count, $frequency.Count, ($count / $frequency.Count), $displayAbove))
            }
        }
        else {
            Write-Output "No lines for analysis."
        }
    }
}