Skip to content
tests-dlf.cpp 10.2 KiB
Newer Older
#include "RaptorQ/v1/common.hpp"
#include "RaptorQ/RaptorQ_v1_hdr.hpp"
#include "RaptorQ/v1/Shared_Computation/Decaying_LF.hpp"
#include <memory>
#include <utility>
#include <algorithm>
#include <iostream>
#include <chrono>
#include <cstdlib>
#include "catch2/catch.hpp"

using namespace RaptorQ__v1::Impl;

TEST_CASE( "Basic", "[Decaying Least Frequency]" )
{
    REQUIRE( DLF<std::vector<uint8_t>, Cache_Key>::get()->get_size() == 0 );
    RaptorQ__v1::local_cache_size (1024);
    REQUIRE( DLF<std::vector<uint8_t>, Cache_Key>::get()->get_size() == 1024 );

    uint16_t size = 347;
    const auto tmp_bool = std::vector<bool>();
    const Cache_Key key(size, 0, 0, tmp_bool, tmp_bool);

    auto data = DLF<std::vector<uint8_t>, Cache_Key>::get()->get(key);
    REQUIRE( data.first == RaptorQ__v1::Compress::NONE );
    REQUIRE( data.second.size() == 0 );

    std::vector<uint8_t> vec(84);
    vec[23] = 43;
    vec[73] = 16;
    vec[76] = 35;
    auto vec_copy = vec;

    auto comp = RaptorQ__v1::Compress::NONE;
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec, key);

    data = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key);
    REQUIRE( data.first == RaptorQ__v1::Compress::NONE );
    REQUIRE( data.second.size() == 84 );
    REQUIRE( data.second == vec_copy );
}

TEST_CASE( "Remove when adding more than limit", "[Decaying Least Frequency]" )
{
    // Remove from previous test
    DLF<std::vector<uint8_t>, Cache_Key>::get()->resize(0);
    int cache_size = 3 * (400 +
                DLF<std::vector<uint8_t>, Cache_Key>::get()->overhead_size());
    auto comp = RaptorQ__v1::Compress::NONE;
    RaptorQ__v1::local_cache_size(cache_size);
    REQUIRE( DLF<std::vector<uint8_t>, Cache_Key>::get()->get_size() == cache_size );

    const auto tmp_bool = std::vector<bool>();
    const Cache_Key key_a(10, 0, 0, tmp_bool, tmp_bool);
    const Cache_Key key_b(101, 0, 0, tmp_bool, tmp_bool);
    const Cache_Key key_c(62, 0, 0, tmp_bool, tmp_bool);
    const Cache_Key key_d(16, 0, 0, tmp_bool, tmp_bool);

    std::vector<uint8_t> vec_a(400);
    std::vector<uint8_t> vec_b(400);
    std::vector<uint8_t> vec_c(400);
    std::vector<uint8_t> vec_d(400);

    // Add 'a', 'b' and 'c'
    auto vec_a_copy = vec_a;
    auto vec_b_copy = vec_b;
    auto vec_c_copy = vec_c;
    auto vec_d_copy = vec_d;
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_a_copy, key_a);
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_b_copy, key_b);
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_c_copy, key_c);

    auto data_a = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_a);
    auto data_b = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_b);
    auto data_c = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_c);
    auto data_d = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_d);

    REQUIRE( data_a.second.size() == 400 );
    REQUIRE( data_b.second.size() == 400 );
    REQUIRE( data_c.second.size() == 400 );
    REQUIRE( data_d.second.size() == 0 ); // Not added yet
    REQUIRE( DLF<std::vector<uint8_t>, Cache_Key>::get()->get_size() == cache_size );

    // Get 'b' and add 'c'
    vec_c_copy = vec_c;
    data_b = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_b);
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_c_copy, key_c);

    // Add 'd'
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_d_copy, key_d);
    data_d = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_d);

    data_a = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_a);
    data_b = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_b);
    data_c = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_c);
    data_d = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_d);

    REQUIRE( data_a.second.size() == 0 ); // Removed when adding d
    REQUIRE( data_b.second.size() == 400 );
    REQUIRE( data_c.second.size() == 400 );
    REQUIRE( data_d.second.size() == 400 );

    // Re-add 'a'
    vec_a_copy = vec_a;
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_a_copy, key_a);

    data_a = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_a);
    data_b = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_b);
    data_c = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_c);
    data_d = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_d);

    REQUIRE( data_a.second.size() == 0 ); // Can't delete
    REQUIRE( data_b.second.size() == 400 );
    REQUIRE( data_c.second.size() == 400 );
    REQUIRE( data_d.second.size() == 400 );

    // Get 'c' and add 'd'
    vec_d_copy = vec_d;
    data_c = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_c);
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_d_copy, key_d);

    // Add 'a'
    vec_a_copy = vec_a;
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_a_copy, key_a);

    data_a = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_a);
    data_b = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_b);
    data_c = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_c);
    data_d = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_d);

    REQUIRE( data_a.second.size() == 400 );
    REQUIRE( data_b.second.size() == 0 ); // Removed
    REQUIRE( data_c.second.size() == 400 );
    REQUIRE( data_d.second.size() == 400 );
}

TEST_CASE( "Remove when resize", "[Decaying Least Frequency]" )
{
    // Remove from previous test
    DLF<std::vector<uint8_t>, Cache_Key>::get()->resize(0);
    int cache_size = 5 * (400 +
                DLF<std::vector<uint8_t>, Cache_Key>::get()->overhead_size());
    auto comp = RaptorQ__v1::Compress::NONE;
    RaptorQ__v1::local_cache_size(cache_size);
    REQUIRE( DLF<std::vector<uint8_t>, Cache_Key>::get()->get_size() == cache_size );

    const auto tmp_bool = std::vector<bool>();
    const Cache_Key key_a(10, 0, 0, tmp_bool, tmp_bool);
    const Cache_Key key_b(101, 0, 0, tmp_bool, tmp_bool);
    const Cache_Key key_c(62, 0, 0, tmp_bool, tmp_bool);
    const Cache_Key key_d(16, 0, 0, tmp_bool, tmp_bool);

    std::vector<uint8_t> vec_a(400);
    std::vector<uint8_t> vec_b(400);
    std::vector<uint8_t> vec_c(400);
    std::vector<uint8_t> vec_d(400);

    // Add 'a', 'b' and 'c'
    auto vec_a_copy = vec_a;
    auto vec_b_copy = vec_b;
    auto vec_c_copy = vec_c;
    auto vec_d_copy = vec_d;
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_a_copy, key_a);
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_b_copy, key_b);
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_c_copy, key_c);
    DLF<std::vector<uint8_t>, Cache_Key>::get()->add(comp, vec_d_copy, key_d);

    auto data_a = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_a);
    auto data_b = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_b);
    auto data_c = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_c);
    auto data_d = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_d);

    REQUIRE( data_a.second.size() == 400 );
    REQUIRE( data_b.second.size() == 400 );
    REQUIRE( data_c.second.size() == 400 );
    REQUIRE( data_d.second.size() == 400 );

    data_a = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_a);
    data_b = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_b);
    data_c = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_c);
    data_d = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_d);

    REQUIRE( data_a.second.size() == 400 );
    REQUIRE( data_b.second.size() == 400 );
    REQUIRE( data_c.second.size() == 400 );
    REQUIRE( data_d.second.size() == 400 );

    // No need to remove
    cache_size = 4 * (400 +
                DLF<std::vector<uint8_t>, Cache_Key>::get()->overhead_size());
    RaptorQ__v1::local_cache_size(cache_size);
    REQUIRE( DLF<std::vector<uint8_t>, Cache_Key>::get()->get_size() == cache_size );

    data_a = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_a);
    data_b = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_b);
    data_c = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_c);
    data_d = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_d);

    REQUIRE( data_a.second.size() == 400 );
    REQUIRE( data_b.second.size() == 400 );
    REQUIRE( data_c.second.size() == 400 );
    REQUIRE( data_d.second.size() == 400 );

    // Remove 'a'
    cache_size = 3 * (400 +
                DLF<std::vector<uint8_t>, Cache_Key>::get()->overhead_size());
    RaptorQ__v1::local_cache_size(cache_size);
    REQUIRE( DLF<std::vector<uint8_t>, Cache_Key>::get()->get_size() == cache_size );

    data_a = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_a);
    data_b = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_b);
    data_c = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_c);
    data_d = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_d);

    REQUIRE( data_a.second.size() == 0 );
    REQUIRE( data_b.second.size() == 400 );
    REQUIRE( data_c.second.size() == 400 );
    REQUIRE( data_d.second.size() == 400 );

    // Remove 'b' and 'c'
    cache_size = (400 +
                DLF<std::vector<uint8_t>, Cache_Key>::get()->overhead_size());
    RaptorQ__v1::local_cache_size(cache_size);
    REQUIRE( DLF<std::vector<uint8_t>, Cache_Key>::get()->get_size() == cache_size );

    data_a = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_a);
    data_b = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_b);
    data_c = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_c);
    data_d = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_d);

    REQUIRE( data_a.second.size() == 0 );
    REQUIRE( data_b.second.size() == 0 );
    REQUIRE( data_c.second.size() == 0 );
    REQUIRE( data_d.second.size() == 400 );

    // Remove 'd'
    cache_size = (400);
    RaptorQ__v1::local_cache_size(cache_size);
    REQUIRE( DLF<std::vector<uint8_t>, Cache_Key>::get()->get_size() == cache_size );

    data_a = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_a);
    data_b = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_b);
    data_c = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_c);
    data_d = DLF<std::vector<uint8_t>, Cache_Key>::get()->get (key_d);

    REQUIRE( data_a.second.size() == 0 );
    REQUIRE( data_b.second.size() == 0 );
    REQUIRE( data_c.second.size() == 0 );
    REQUIRE( data_d.second.size() == 0 );
}