mirror of
				https://github.com/facebook/zstd.git
				synced 2025-11-03 20:33:11 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			174 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 | 
						|
 * All rights reserved.
 | 
						|
 *
 | 
						|
 * This source code is licensed under both the BSD-style license (found in the
 | 
						|
 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
 | 
						|
 * in the COPYING file in the root directory of this source tree).
 | 
						|
 * You may select, at your option, one of the above-listed licenses.
 | 
						|
 */
 | 
						|
 | 
						|
#include "zstdcli_trace.h"
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
 | 
						|
#include "timefn.h"
 | 
						|
#include "util.h"
 | 
						|
 | 
						|
#define ZSTD_STATIC_LINKING_ONLY
 | 
						|
#include "../lib/zstd.h"
 | 
						|
/* We depend on the trace header to avoid duplicating the ZSTD_trace struct.
 | 
						|
 * But, we check the version so it is compatible with dynamic linking.
 | 
						|
 */
 | 
						|
#include "../lib/common/zstd_trace.h"
 | 
						|
/* We only use macros from threading.h so it is compatible with dynamic linking */
 | 
						|
#include "../lib/common/threading.h"
 | 
						|
 | 
						|
#if ZSTD_TRACE
 | 
						|
 | 
						|
static FILE* g_traceFile = NULL;
 | 
						|
static int g_mutexInit = 0;
 | 
						|
static ZSTD_pthread_mutex_t g_mutex;
 | 
						|
static UTIL_time_t g_enableTime = UTIL_TIME_INITIALIZER;
 | 
						|
 | 
						|
void TRACE_enable(char const* filename)
 | 
						|
{
 | 
						|
    int const writeHeader = !UTIL_isRegularFile(filename);
 | 
						|
    if (g_traceFile)
 | 
						|
        fclose(g_traceFile);
 | 
						|
    g_traceFile = fopen(filename, "a");
 | 
						|
    if (g_traceFile && writeHeader) {
 | 
						|
        /* Fields:
 | 
						|
        * algorithm
 | 
						|
        * version
 | 
						|
        * method
 | 
						|
        * streaming
 | 
						|
        * level
 | 
						|
        * workers
 | 
						|
        * dictionary size
 | 
						|
        * uncompressed size
 | 
						|
        * compressed size
 | 
						|
        * duration nanos
 | 
						|
        * compression ratio
 | 
						|
        * speed MB/s
 | 
						|
        */
 | 
						|
        fprintf(g_traceFile, "Algorithm, Version, Method, Mode, Level, Workers, Dictionary Size, Uncompressed Size, Compressed Size, Duration Nanos, Compression Ratio, Speed MB/s\n");
 | 
						|
    }
 | 
						|
    g_enableTime = UTIL_getTime();
 | 
						|
    if (!g_mutexInit) {
 | 
						|
        if (!ZSTD_pthread_mutex_init(&g_mutex, NULL)) {
 | 
						|
            g_mutexInit = 1;
 | 
						|
        } else {
 | 
						|
            TRACE_finish();
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void TRACE_finish(void)
 | 
						|
{
 | 
						|
    if (g_traceFile) {
 | 
						|
        fclose(g_traceFile);
 | 
						|
    }
 | 
						|
    g_traceFile = NULL;
 | 
						|
    if (g_mutexInit) {
 | 
						|
        ZSTD_pthread_mutex_destroy(&g_mutex);
 | 
						|
        g_mutexInit = 0;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void TRACE_log(char const* method, PTime duration, ZSTD_Trace const* trace)
 | 
						|
{
 | 
						|
    int level = 0;
 | 
						|
    int workers = 0;
 | 
						|
    double const durationAsDouble = duration ? (double)duration : .1;
 | 
						|
    double const ratio = (double)trace->uncompressedSize / (double)trace->compressedSize;
 | 
						|
    double const speed = ((double)trace->uncompressedSize * 1000) / durationAsDouble;
 | 
						|
    if (trace->params) {
 | 
						|
        ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_compressionLevel, &level);
 | 
						|
        ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_nbWorkers, &workers);
 | 
						|
    }
 | 
						|
    assert(g_traceFile != NULL);
 | 
						|
 | 
						|
    ZSTD_pthread_mutex_lock(&g_mutex);
 | 
						|
    /* Fields:
 | 
						|
     * algorithm
 | 
						|
     * version
 | 
						|
     * method
 | 
						|
     * streaming
 | 
						|
     * level
 | 
						|
     * workers
 | 
						|
     * dictionary size
 | 
						|
     * uncompressed size
 | 
						|
     * compressed size
 | 
						|
     * duration nanos
 | 
						|
     * compression ratio
 | 
						|
     * speed MB/s
 | 
						|
     */
 | 
						|
    fprintf(g_traceFile,
 | 
						|
        "zstd, %u, %s, %s, %d, %d, %llu, %llu, %llu, %llu, %.2f, %.2f\n",
 | 
						|
        trace->version,
 | 
						|
        method,
 | 
						|
        trace->streaming ? "streaming" : "single-pass",
 | 
						|
        level,
 | 
						|
        workers,
 | 
						|
        (unsigned long long)trace->dictionarySize,
 | 
						|
        (unsigned long long)trace->uncompressedSize,
 | 
						|
        (unsigned long long)trace->compressedSize,
 | 
						|
        (unsigned long long)duration,
 | 
						|
        ratio,
 | 
						|
        speed);
 | 
						|
    ZSTD_pthread_mutex_unlock(&g_mutex);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * These symbols override the weak symbols provided by the library.
 | 
						|
 */
 | 
						|
 | 
						|
ZSTD_TraceCtx ZSTD_trace_compress_begin(ZSTD_CCtx const* cctx)
 | 
						|
{
 | 
						|
    (void)cctx;
 | 
						|
    if (g_traceFile == NULL)
 | 
						|
        return 0;
 | 
						|
    return (ZSTD_TraceCtx)UTIL_clockSpanNano(g_enableTime);
 | 
						|
}
 | 
						|
 | 
						|
void ZSTD_trace_compress_end(ZSTD_TraceCtx ctx, ZSTD_Trace const* trace)
 | 
						|
{
 | 
						|
    PTime const beginNanos = (PTime)ctx;
 | 
						|
    PTime const endNanos = UTIL_clockSpanNano(g_enableTime);
 | 
						|
    PTime const durationNanos = endNanos > beginNanos ? endNanos - beginNanos : 0;
 | 
						|
    assert(g_traceFile != NULL);
 | 
						|
    assert(trace->version == ZSTD_VERSION_NUMBER); /* CLI version must match. */
 | 
						|
    TRACE_log("compress", durationNanos, trace);
 | 
						|
}
 | 
						|
 | 
						|
ZSTD_TraceCtx ZSTD_trace_decompress_begin(ZSTD_DCtx const* dctx)
 | 
						|
{
 | 
						|
    (void)dctx;
 | 
						|
    if (g_traceFile == NULL)
 | 
						|
        return 0;
 | 
						|
    return (ZSTD_TraceCtx)UTIL_clockSpanNano(g_enableTime);
 | 
						|
}
 | 
						|
 | 
						|
void ZSTD_trace_decompress_end(ZSTD_TraceCtx ctx, ZSTD_Trace const* trace)
 | 
						|
{
 | 
						|
    PTime const beginNanos = (PTime)ctx;
 | 
						|
    PTime const endNanos = UTIL_clockSpanNano(g_enableTime);
 | 
						|
    PTime const durationNanos = endNanos > beginNanos ? endNanos - beginNanos : 0;
 | 
						|
    assert(g_traceFile != NULL);
 | 
						|
    assert(trace->version == ZSTD_VERSION_NUMBER); /* CLI version must match. */
 | 
						|
    TRACE_log("decompress", durationNanos, trace);
 | 
						|
}
 | 
						|
 | 
						|
#else /* ZSTD_TRACE */
 | 
						|
 | 
						|
void TRACE_enable(char const* filename)
 | 
						|
{
 | 
						|
    (void)filename;
 | 
						|
}
 | 
						|
 | 
						|
void TRACE_finish(void) {}
 | 
						|
 | 
						|
#endif /* ZSTD_TRACE */
 |