fastpfor 0.9.0

FastPFOR lib with C++ Rust wrapper and pure Rust implementation
#include <vector>
#include <memory>
#include <limits>
#include <random>
#include <cmath>

#include "gtest/gtest.h"

#include "codecs.h"
#include "variablebyte.h"

namespace FastPForLib {

  class VariableByteTest : public ::testing::Test {
    public:
      virtual void SetUp();

      protected:
        std::unique_ptr<VariableByte> codec;
        std::vector<int32_t> in32;
        std::vector<int64_t> in64;
        std::vector<uint32_t> encoded;
        std::vector<int32_t> out32;
        std::vector<int64_t> out64;

        void _verify() {
          size_t inSize = in32.size();
          encoded.resize(in32.size() * 2);
          size_t encodeSize = encoded.size();

          codec->encodeArray(
                             reinterpret_cast<uint32_t *>(in32.data()),
                             inSize,
                             encoded.data(),
                             encodeSize);

          out32.resize(inSize);
          codec->decodeArray(
                             encoded.data(),
                             encodeSize,
                             reinterpret_cast<uint32_t *>(out32.data()),
                             inSize);

          bool passed = true;
          for (size_t i = 0; i < inSize; ++i) {
            if (in32[i] != out32[i]) {
              passed = false;
            }
            EXPECT_EQ(in32[i], out32[i]);
          }
          if (!passed) {
            std::cout << "Test failed with int32 input: ";
            for (size_t i = 0; i < inSize; ++i) {
              std::cout << in32[i] << " ";
            }
            std::cout << std::endl;
          }
        }

        void _verify64() {
          size_t inSize = in64.size();
          encoded.resize(in64.size() * 4);
          size_t encodeSize = encoded.size();

          codec->encodeArray(
                             reinterpret_cast<uint64_t *>(in64.data()),
                             inSize,
                             encoded.data(),
                             encodeSize);

          out64.resize(inSize);
          codec->decodeArray(
                             encoded.data(),
                             encodeSize,
                             reinterpret_cast<uint64_t *>(out64.data()),
                             inSize);

          bool passed = true;
          for (size_t i = 0; i < inSize; ++i) {
            if (in64[i] != out64[i]) {
              passed = false;
            }
            EXPECT_EQ(in64[i], out64[i]);
          }
          if (!passed) {
            std::cout << "Test failed with int64 input: ";
            for (size_t i = 0; i < inSize; ++i) {
              std::cout << in64[i] << " ";
            }
            std::cout << std::endl;
          }
        }
    };

  void VariableByteTest::SetUp() {
    codec.reset(new VariableByte());
  }

  TEST_F(VariableByteTest, emptyArray) {
    in32.resize(0);
    out32.resize(0);
    _verify();
  }

  TEST_F(VariableByteTest, emptyArray64) {
    in64.resize(0);
    out64.resize(0);
    _verify64();
  }

  TEST_F(VariableByteTest, increasingSequence) {
    in32.resize(0);
    for (int i = -20; i < 1000; ++i) {
      in32.push_back(i);
    }
    _verify();
  }

  TEST_F(VariableByteTest, maxAndMin) {
    in32.resize(0);
    in32.push_back(std::numeric_limits<int32_t>::min());
    in32.push_back(0);
    in32.push_back(std::numeric_limits<int32_t>::max());
    _verify();
  }

  TEST_F(VariableByteTest, increasingSequence64) {
    in64.resize(0);
    for (int i = -25; i < 1111; ++i) {
      in64.push_back(i);
    }
    _verify();
  }

  TEST_F(VariableByteTest, negativeIncreasingSequence64) {
    in64.resize(0);
    int64_t start = -9223372036854775800;
    for (int64_t i = 0; i < 3000; ++i) {
      in64.push_back(start + i);
    }
    _verify64();
  }

  TEST_F(VariableByteTest, positiveDecreasingSequence64) {
    in64.resize(0);
    int64_t start = 9223372036854775800;
    for (int64_t i = 0; i < 1555; ++i) {
      in64.push_back(start - i);
    }
    _verify64();
  }

  TEST_F(VariableByteTest, maxAndMin64) {
    in64.resize(0);
    in64.push_back(std::numeric_limits<int64_t>::min());
    in64.push_back(0);
    in64.push_back(std::numeric_limits<int64_t>::max());
    _verify64();
  }

  TEST_F(VariableByteTest, sequenceHasBoth32And64) {
    in64.resize(0);
    in64.push_back(-9223372036854775000);
    in64.push_back(-32767);
    in64.push_back(-300);
    in64.push_back(0);
    in64.push_back(500);
    in64.push_back(32767);
    in64.push_back(65536);
    in64.push_back(2147483647);
    in64.push_back(4294967295);
    in64.push_back(8223372036854775800);
    _verify64();
  }

  TEST_F(VariableByteTest, randomNumbers5000) {
    in64.resize(0);
    std::mt19937_64 e2(123456);
    std::uniform_int_distribution<int64_t> dist(
                            std::numeric_limits<int64_t>::min(),
                            std::numeric_limits<int64_t>::max());
    for (int i = 0; i < 5000; ++i) {
      in64.push_back(dist(e2));
    }
    _verify64();
  }
}