UNPKG

harperdb

Version:

HarperDB is a distributed database, caching service, streaming broker, and application development platform focused on performance and ease of use.

132 lines (128 loc) 4.84 kB
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 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); } */