type ActionCallback = (action: Action) => void;
export type Value = number | boolean | ActionCallback;
interface Action {
    total?: number;
    values?: Float32Array;
    count?: number;
    callback?: ActionCallback;
    description?: {
        metric: string;
        path: string;
        method: string;
        type: string;
    };
}
export declare function setAnalyticsEnabled(enabled: boolean): void;
/**
 * Record an action for analytics (like an HTTP request, replication, MQTT message)
 * @param value
 * @param metric
 * @param path
 * @param method
 * @param type
 */
export declare function recordAction(value: Value, metric: string, path?: string, method?: string, type?: string): void;
export declare function recordActionBinary(value: any, metric: any, path?: any, method?: any, type?: any): void;
export declare const analyticsDelay = 1000;
export declare function addAnalyticsListener(callback: any): void;
export declare function recordHostname(): Promise<void>;
export interface Metric {
    [key: string]: any;
}
interface ResourceUsage extends Partial<NodeJS.ResourceUsage> {
    time?: number;
    period?: number;
    cpuUtilization?: number;
    userCPUTime?: number;
    systemCPUTime?: number;
}
/** calculateCPUUtilization takes a ResourceUsage with at least userCPUTime &
 *  systemCPUTime set with millisecond values and a time period in milliseconds
 *  and returns the percentage of that time the CPU was being utilized as a
 *  decimal value between 0 and 1. So for example, 50% utilization will be
 *  returned as 0.5.
 */
export declare function calculateCPUUtilization(resourceUsage: ResourceUsage, period: number): number;
/** diffResourceUsage takes a ResourceUsage representing the last time we stored them and a new
 *  process.resourceUsage() return value and normalizes and diffs the two values to return the
 *  new values for this time period.
 */
export declare function diffResourceUsage(lastResourceUsage: ResourceUsage, resourceUsage: ResourceUsage): ResourceUsage;
export declare function getDirectorySizeAsync(dirPath: string): Promise<number>;
export declare function onAnalyticsAggregate(callback: any): void;
export {};
/**
 * This section contains a possible/experimental approach to bucketing values as they come instead of pushing all into an array and sorting.
 *
const BUCKET_COUNT = 100;
function addToBucket(action, value) {
    if (!action.buckets) {
        action.buckets = newBuckets();
    }
    const { counts, values, totalCount } = action.buckets;
    let jump = BUCKET_COUNT >> 1; // amount to jump with each iteration
    let position = jump; // start at halfway point
    while ((jump = jump >> 1) > 0) {
        const bucketValue = values[position];
        if (bucketValue === 0) {
            // unused slot, immediately put our value in
            counts[position] = 1;
            values[position] = value;
        }
        if (value > bucketValue) {
            position += jump;
        } else {
            position -= jump;
        }
    }
    const count = counts[position] + 1;
    if (position === BUCKET_COUNT) {
        // if we go beyond the last item, increase the bucket (max) value
        position--;
        values[position] = value;
    }
    if (count > threshold) {
        rebalance(action.buckets, false);
    } else {
        counts[position] = count;
    }
}

function newBuckets() {
    const ab = new ArrayBuffer(8 * BUCKET_COUNT);
    return {
        values: new Float32Array(ab, 0, BUCKET_COUNT),
        counts: new Uint32Array(ab, BUCKET_COUNT * 4, BUCKET_COUNT),
        totalCount: 0,
    };
}

let balancingBuckets;

 /**
 * Rebalance the buckets, we can reset the counts at the same time, if this occurred after a delivery
 * @param param
 * @param resetCounts
 *
function rebalance({ counts, values, totalCount }, resetCounts: boolean) {
    const countPerBucket = totalCount / BUCKET_COUNT;
    let targetPosition = 0;
    let targetCount = 0;
    let lastTargetValue = 0;
    const { values: targetValues, counts: targetCounts } = balancingBuckets || (balancingBuckets = newBuckets());
    for (let i = 0; i < BUCKET_COUNT; i++) {
        // iterate through the existing buckets, filling up the target buckets in a balanced way
        let count = counts[i];
        while ((countPerBucket - targetCount) < count) {
            const value = values[i];
            lastTargetValue = ((countPerBucket - targetCount) / count) * (value - lastTargetValue) + lastTargetValue;
            targetValues[targetPosition] = lastTargetValue;
            targetCounts[targetPosition] = countPerBucket;
            count -= countPerBucket;
            targetPosition++;
            targetCount = 0;
        }
        targetCount += count;
    }
    // now copy the balanced buckets back into the original buckets
    values.set(targetValues);
    if (resetCounts) counts.fill(0);
    else counts.set(targetCounts);
}
*/
