// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Benchmarks in-memory compression and decompression of an input file,
// comparing zlib and snappy.

#include <memory>
#include <string>

#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/time/time.h"
#include "third_party/brotli/include/brotli/decode.h"
#include "third_party/brotli/include/brotli/encode.h"
#include "third_party/snappy/src/snappy.h"
#include "third_party/zlib/google/compression_utils.h"

namespace {

enum class CompressionType { kSnappy, kZlib, kBrotli };

void LogResults(CompressionType compression_type,
                bool compression,
                size_t chunk_size,
                size_t chunk_count,
                double compression_ratio,
                base::TimeTicks tick,
                base::TimeTicks tock) {
  size_t total_size = chunk_size * chunk_count;
  double elapsed_us = (tock - tick).InMicrosecondsF();
  double throughput = total_size / elapsed_us;
  double latency_us = elapsed_us / chunk_count;

  std::string compression_name;
  switch (compression_type) {
    case CompressionType::kSnappy:
      compression_name = "snappy";
      break;
    case CompressionType::kZlib:
      compression_name = "zlib";
      break;
    case CompressionType::kBrotli:
      compression_name = "brotli";
      break;
  }
  LOG(INFO) << compression_name << ","
            << (compression ? "compression" : "decompression") << ","
            << chunk_size << "," << throughput << "," << latency_us << ","
            << compression_ratio;
}

void CompressChunks(const std::string& contents,
                    size_t chunk_size,
                    CompressionType compression_type,
                    std::vector<std::string>* compressed_chunks) {
  CHECK(compressed_chunks);
  size_t chunk_count = contents.size() / chunk_size;

  for (size_t i = 0; i < chunk_count; ++i) {
    std::string compressed;
    base::StringPiece input(contents.c_str() + i * chunk_size, chunk_size);

    switch (compression_type) {
      case CompressionType::kSnappy:
        CHECK(snappy::Compress(input.data(), input.size(), &compressed));
        break;
      case CompressionType::kZlib:
        CHECK(compression::GzipCompress(input, &compressed));
        break;
      case CompressionType::kBrotli: {
        std::vector<uint8_t> compressed_data(
            BrotliEncoderMaxCompressedSize(input.size()));
        size_t encoded_size = compressed_data.size();
        CHECK(BrotliEncoderCompress(
            3, BROTLI_DEFAULT_WINDOW, BROTLI_DEFAULT_MODE, input.size(),
            reinterpret_cast<const uint8_t*>(input.data()), &encoded_size,
            reinterpret_cast<uint8_t*>(&compressed_data[0])));
        compressed.assign(reinterpret_cast<const char*>(&compressed_data[0]),
                          encoded_size);
      } break;
    }

    compressed_chunks->push_back(compressed);
  }
}

void BenchmarkDecompression(const std::string& contents,
                            size_t chunk_size,
                            CompressionType compression_type) {
  std::vector<std::string> compressed_chunks;
  CompressChunks(contents, chunk_size, compression_type, &compressed_chunks);

  auto tick = base::TimeTicks::Now();
  for (const auto& chunk : compressed_chunks) {
    std::string uncompressed;
    switch (compression_type) {
      case CompressionType::kSnappy:
        snappy::Uncompress(chunk.c_str(), chunk.size(), &uncompressed);
        break;
      case CompressionType::kZlib:
        CHECK(compression::GzipUncompress(chunk, &uncompressed));
        break;
      case CompressionType::kBrotli: {
        size_t decoded_size = chunk_size;
        std::vector<uint8_t> decoded_data(chunk_size);
        CHECK(BrotliDecoderDecompress(
            chunk.size(), reinterpret_cast<const uint8_t*>(&chunk[0]),
            &decoded_size, &decoded_data[0]));
        CHECK_EQ(chunk_size, decoded_size);
      } break;
    }
  }
  auto tock = base::TimeTicks::Now();

  LogResults(compression_type, false, chunk_size, compressed_chunks.size(), 0.,
             tick, tock);
}

void BenchmarkCompression(const std::string& contents,
                          size_t chunk_size,
                          CompressionType compression_type) {
  auto tick = base::TimeTicks::Now();
  std::vector<std::string> compressed_chunks;
  CompressChunks(contents, chunk_size, compression_type, &compressed_chunks);
  auto tock = base::TimeTicks::Now();

  size_t compressed_size = 0;
  for (const auto& compressed_chunk : compressed_chunks)
    compressed_size += compressed_chunk.size();

  double ratio = contents.size() / static_cast<double>(compressed_size);
  LogResults(compression_type, true, chunk_size, compressed_chunks.size(),
             ratio, tick, tock);
}

}  // namespace

int main(int argc, char** argv) {
  if (argc != 2) {
    LOG(FATAL) << "Usage: " << argv[0] << " <filename>\n\n"
               << "Where the file contains data to compress";
    return 1;
  }

  LOG(INFO) << "Reading the input file";
  auto path = base::FilePath(std::string(argv[1]));
  std::string contents;
  CHECK(base::ReadFileToString(path, &contents));

  // Make sure we have at least 40MiB.
  constexpr size_t kPageSize = 1 << 12;
  constexpr size_t target_size = 40 * 1024 * 1024;
  std::string repeated_contents;
  size_t repeats = target_size / contents.size() + 1;

  repeated_contents.reserve(repeats * contents.size());
  for (size_t i = 0; i < repeats; ++i)
    repeated_contents.append(contents);

  for (CompressionType compression_type :
       {CompressionType::kSnappy, CompressionType::kZlib,
        CompressionType::kBrotli}) {
    for (size_t size = kPageSize; size < contents.size(); size *= 2) {
      BenchmarkCompression(repeated_contents, size, compression_type);
      BenchmarkDecompression(repeated_contents, size, compression_type);
    }
  }
  return 0;
}
