/*
 * 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.
 */

 /* benchzstd :
  * benchmark Zstandard compression / decompression
  * over a set of files or buffers
  * and display progress result and final summary
  */

#ifndef BENCH_ZSTD_H_3242387
#define BENCH_ZSTD_H_3242387

/* ===  Dependencies  === */
#include <stddef.h>   /* size_t */
#define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_compressionParameters */
#include "../lib/zstd.h"     /* ZSTD_compressionParameters */

/* ===  Constants  === */

#define MB_UNIT 1000000


/* ===  Benchmark functions  === */

/* Creates a variant `typeName`, able to express "error or valid result".
 * Functions with return type `typeName`
 * must first check if result is valid, using BMK_isSuccessful_*(),
 * and only then can extract `baseType`.
 */
#define VARIANT_ERROR_RESULT(baseType, variantName)  \
                                             \
typedef struct {                             \
    baseType internal_never_use_directly;    \
    int tag;                                 \
} variantName


typedef struct {
    size_t cSize;
    unsigned long long cSpeed;   /* bytes / sec */
    unsigned long long dSpeed;
    size_t cMem;                 /* memory usage during compression */
} BMK_benchResult_t;

VARIANT_ERROR_RESULT(BMK_benchResult_t, BMK_benchOutcome_t);

/* check first if the return structure represents an error or a valid result */
int BMK_isSuccessful_benchOutcome(BMK_benchOutcome_t outcome);

/* extract result from variant type.
 * note : this function will abort() program execution if result is not valid
 *        check result validity first, by using BMK_isSuccessful_benchOutcome()
 */
BMK_benchResult_t BMK_extract_benchResult(BMK_benchOutcome_t outcome);


/*! BMK_benchFiles() -- called by zstdcli */
/*  Loads files from fileNamesTable into memory,
 *  and an optional dictionary from dictFileName (can be NULL),
 *  then uses benchMem().
 *  fileNamesTable - name of files to benchmark.
 *  nbFiles - number of files (size of fileNamesTable), must be > 0.
 *  dictFileName - name of dictionary file to load.
 *  cLevel - compression level to benchmark, errors if invalid.
 *  compressionParams - advanced compression Parameters.
 *  displayLevel - what gets printed:
 *      0 : no display;
 *      1 : errors;
 *      2 : + result + interaction + warnings;
 *      3 : + information;
 *      4 : + debug
 * @return: 0 on success, !0 on error
 */
int BMK_benchFiles(
            const char* const * fileNamesTable, unsigned nbFiles,
            const char* dictFileName,
            int cLevel, const ZSTD_compressionParameters* compressionParams,
            int displayLevel);


typedef enum {
    BMK_both = 0,
    BMK_decodeOnly = 1,
    BMK_compressOnly = 2
} BMK_mode_t;

typedef struct {
    BMK_mode_t mode;        /* 0: both, 1: compress only 2: decode only */
    unsigned nbSeconds;     /* default timing is in nbSeconds */
    size_t chunkSizeMax;    /* Maximum size of each independent chunk */
    size_t targetCBlockSize;/* Approximative size of compressed blocks */
    int nbWorkers;          /* multithreading */
    unsigned realTime;      /* real time priority */
    int additionalParam;    /* used by python speed benchmark */
    int ldmFlag;            /* enables long distance matching */
    int ldmMinMatch;        /* below: parameters for long distance matching, see zstd.1.md */
    int ldmHashLog;
    int ldmBucketSizeLog;
    int ldmHashRateLog;
    ZSTD_ParamSwitch_e literalCompressionMode;
    int useRowMatchFinder;  /* use row-based matchfinder if possible */
} BMK_advancedParams_t;

/* returns default parameters used by nonAdvanced functions */
BMK_advancedParams_t BMK_initAdvancedParams(void);

/*! BMK_benchFilesAdvanced():
 *  Same as BMK_benchFiles(),
 *  with more controls, provided through advancedParams_t structure */
int BMK_benchFilesAdvanced(
               const char* const * fileNamesTable, unsigned nbFiles,
               const char* dictFileName,
               int startCLevel, int endCLevel,
               const ZSTD_compressionParameters* compressionParams,
               int displayLevel, const BMK_advancedParams_t* adv);

/*! BMK_syntheticTest() -- called from zstdcli */
/*  Generates a sample with datagen, using @compressibility argument
 * @cLevel - compression level to benchmark, errors if invalid
 * @compressibility - determines compressibility of sample, range [0.0 - 1.0]
 *        if @compressibility < 0.0, uses the lorem ipsum generator
 * @compressionParams - basic compression Parameters
 * @displayLevel - see benchFiles
 * @adv - see advanced_Params_t
 * @return: 0 on success, !0 on error
 */
int BMK_syntheticTest(double compressibility,
                      int startingCLevel, int endCLevel,
                      const ZSTD_compressionParameters* compressionParams,
                      int displayLevel, const BMK_advancedParams_t* adv);



/* ===  Benchmark Zstandard in a memory-to-memory scenario  === */

/** BMK_benchMem() -- core benchmarking function, called in paramgrill
 *  applies ZSTD_compress_generic() and ZSTD_decompress_generic() on data in srcBuffer
 *  with specific compression parameters provided by other arguments using benchFunction
 *  (cLevel, comprParams + adv in advanced Mode) */
/*  srcBuffer - data source, expected to be valid compressed data if in Decode Only Mode
 *  srcSize - size of data in srcBuffer
 *  fileSizes - srcBuffer is considered cut into 1+ segments, to compress separately.
 *              note : sum(fileSizes) must be == srcSize.  (<== ensure it's properly checked)
 *  nbFiles - nb of segments
 *  cLevel - compression level
 *  comprParams - basic compression parameters
 *  dictBuffer - a dictionary if used, null otherwise
 *  dictBufferSize - size of dictBuffer, 0 otherwise
 *  displayLevel - see BMK_benchFiles
 *  displayName - name used by display
 * @return:
 *      a variant, which expresses either an error, or a valid result.
 *      Use BMK_isSuccessful_benchOutcome() to check if function was successful.
 *      If yes, extract the valid result with BMK_extract_benchResult(),
 *      it will contain :
 *          .cSpeed: compression speed in bytes per second,
 *          .dSpeed: decompression speed in bytes per second,
 *          .cSize : compressed size, in bytes
 *          .cMem  : memory budget required for the compression context
 */
BMK_benchOutcome_t BMK_benchMem(const void* srcBuffer, size_t srcSize,
                        const size_t* fileSizes, unsigned nbFiles,
                        int cLevel, const ZSTD_compressionParameters* comprParams,
                        const void* dictBuffer, size_t dictBufferSize,
                        int displayLevel, const char* displayName);


/* BMK_benchMemAdvanced() : used by Paramgrill
 * same as BMK_benchMem() with following additional options :
 * dstBuffer - destination buffer to write compressed output in, NULL if none provided.
 * dstCapacity - capacity of destination buffer, give 0 if dstBuffer = NULL
 * adv = see advancedParams_t
 */
BMK_benchOutcome_t BMK_benchMemAdvanced(const void* srcBuffer, size_t srcSize,
                        void* dstBuffer, size_t dstCapacity,
                        const size_t* fileSizes, unsigned nbFiles,
                        int cLevel, const ZSTD_compressionParameters* comprParams,
                        const void* dictBuffer, size_t dictBufferSize,
                        int displayLevel, const char* displayName,
                        const BMK_advancedParams_t* adv);



#endif   /* BENCH_ZSTD_H_3242387 */
