<commit_before>// thread_id.cpp
//
#include "dataserver/bpool/thread_id.h"

namespace sdl { namespace db { namespace bpool { 

thread_mask_t::thread_mask_t(size_t const filesize)
    : m_index_count(round_up_div(filesize, index_size))
    , m_block_count(round_up_div(filesize, (size_t)block_size))
{
    SDL_ASSERT(m_index_count <= max_index);
    SDL_ASSERT(m_block_count <= pool_limits::max_block);
    static_assert(index_block_num == 8192, "");
    static_assert(!(index_block_num % mask_div), "");
    static_assert(sizeof(mask_t) == 1024, "");
    m_index.resize(m_index_count);
}

void thread_mask_t::shrink_to_fit() {
    for (mask_p & p : m_index) {
        if (p && empty(*p)) {
            p.reset();
        }
    }
}

void thread_mask_t::clear() {
    for (mask_p & p : m_index) {
        p.reset();
    }
}

//-------------------------------------------------------------

thread_id_t::pos_mask
thread_id_t::find(id_type const id) {
#if defined(SDL_THREAD_ID_USE_HASH)
    if (use_hash) {
        const size_t h = hash_id(id);
        id_mask const & x = m_data[h];
        if ((x.first == id) && (x.second != nullptr)) {
            return { h, x.second.get() };
        }
    }
#endif
    const auto pos = std::find_if(m_data.begin(), m_data.end(),
        [id](id_mask const & x){
        return (x.first == id) && (x.second != nullptr);
    });
    if (pos != m_data.end()) {
        const size_t d = std::distance(m_data.begin(), pos);
        return { d, pos->second.get() };
    }
    return{ max_thread, nullptr };
}

thread_id_t::pos_mask
thread_id_t::insert(id_type const id) {
#if defined(SDL_THREAD_ID_USE_HASH)
    if (use_hash) {
        const size_t h = hash_id(id);
        id_mask & x = m_data[h];
        if ((x.first == id) || (x.second == nullptr)) {
            if (!x.second) { // empty slot is found
                x.first = id;
                reset_new(x.second, m_filesize);
                SDL_ASSERT(m_size < max_size());
                ++m_size;
            }
            return { h, x.second.get() };
        }
    }
#endif
    const auto pos = std::find_if(m_data.begin(), m_data.end(),
        [id](id_mask const & x){
        return (x.first == id) || (x.second == nullptr);
    });
    if (pos == m_data.end()) {
        //FIXME: wait until thread is released ?
        throw_error_t<thread_id_t>("too many threads");
        return { max_thread, nullptr };
    }
    if (!pos->second) { // empty slot is found
        pos->first = id;
        reset_new(pos->second, m_filesize);
        SDL_ASSERT(m_size < max_size());
        ++m_size;
        SDL_TRACE("thread_insert = ", id);
    }
    const auto d = static_cast<size_t>(std::distance(m_data.begin(), pos));
    return { d, pos->second.get() };
}

bool thread_id_t::erase(id_type const id) {
#if defined(SDL_THREAD_ID_USE_HASH)
    if (use_hash) {
        const size_t h = hash_id(id);
        id_mask & x = m_data[h];
        if ((x.first == id) && (x.second != nullptr)) {
            x = {};
            SDL_ASSERT(m_size);
            --m_size;
            return true;
        }
    }
#endif
    const auto pos = std::find_if(m_data.begin(), m_data.end(),
        [id](id_mask const & x){
        return (x.first == id) && (x.second != nullptr);
    });
    if (pos != m_data.end()) {
        *pos = {};
        SDL_ASSERT(m_size);
        --m_size;
        SDL_TRACE("* thread_erase = ", id);
        return true;
    }
    return false;
}

#if SDL_DEBUG
namespace {
    inline constexpr uint32_t knuth_hash(uint32_t v) {
        return (v * UINT32_C(2654435761)) % thread_id_t::max_size();
    }
    class unit_test {
        void test_thread();
        void test_mask(size_t);
    public:
        unit_test() {
            static_assert(power_of<64>::value == 6, "");
            if (0) {
                test_mask(gigabyte<8>::value);
                //test_mask(terabyte<1>::value);
            }
            if (0) {
                try {
                    test_thread();
                }
                catch(sdl_exception & e) {
                    std::cout << "exception = " << e.what() << std::endl;
                }
            }
            if (0) {
            }
        }
    };
    void unit_test::test_mask(size_t const filesize) {
        thread_mask_t test(filesize);
        for (size_t i = 0; i < test.size(); ++i) {
            SDL_ASSERT(!test[i]);
            test.set_block(i);
            SDL_ASSERT(test[i]);
            if (i >= 8192)
                test.clr_block(i);
        }
        test.clr_block(test.size()-1);
        test.shrink_to_fit();
    }
    void unit_test::test_thread() {
        thread_id_t test(gigabyte<8>::value);
        auto pos = test.insert();
        SDL_ASSERT(pos.first.value() == test.insert().first.value());
        const auto id = test.get_id();
        SDL_ASSERT(test.find(id).first.value() < pool_limits::max_thread);
        SDL_ASSERT(test.find(id).second);
        SDL_ASSERT(test.erase(id));
        SDL_ASSERT(!test.erase(id));
        SDL_ASSERT(!test.find(id).second);
        SDL_TRACE_FUNCTION;
    }
    static unit_test s_test;
}
#endif //#if SDL_DEBUG
}}} // sdl
<commit_msg>trace thread_id_t::erase<commit_after>// thread_id.cpp
//
#include "dataserver/bpool/thread_id.h"

namespace sdl { namespace db { namespace bpool { 

thread_mask_t::thread_mask_t(size_t const filesize)
    : m_index_count(round_up_div(filesize, index_size))
    , m_block_count(round_up_div(filesize, (size_t)block_size))
{
    SDL_ASSERT(m_index_count <= max_index);
    SDL_ASSERT(m_block_count <= pool_limits::max_block);
    static_assert(index_block_num == 8192, "");
    static_assert(!(index_block_num % mask_div), "");
    static_assert(sizeof(mask_t) == 1024, "");
    m_index.resize(m_index_count);
}

void thread_mask_t::shrink_to_fit() {
    for (mask_p & p : m_index) {
        if (p && empty(*p)) {
            p.reset();
        }
    }
}

void thread_mask_t::clear() {
    for (mask_p & p : m_index) {
        p.reset();
    }
}

//-------------------------------------------------------------

thread_id_t::pos_mask
thread_id_t::find(id_type const id) {
#if defined(SDL_THREAD_ID_USE_HASH)
    if (use_hash) {
        const size_t h = hash_id(id);
        id_mask const & x = m_data[h];
        if ((x.first == id) && (x.second != nullptr)) {
            return { h, x.second.get() };
        }
    }
#endif
    const auto pos = std::find_if(m_data.begin(), m_data.end(),
        [id](id_mask const & x){
        return (x.first == id) && (x.second != nullptr);
    });
    if (pos != m_data.end()) {
        const size_t d = std::distance(m_data.begin(), pos);
        return { d, pos->second.get() };
    }
    return{ max_thread, nullptr };
}

thread_id_t::pos_mask
thread_id_t::insert(id_type const id) {
#if defined(SDL_THREAD_ID_USE_HASH)
    if (use_hash) {
        const size_t h = hash_id(id);
        id_mask & x = m_data[h];
        if ((x.first == id) || (x.second == nullptr)) {
            if (!x.second) { // empty slot is found
                x.first = id;
                reset_new(x.second, m_filesize);
                SDL_ASSERT(m_size < max_size());
                ++m_size;
            }
            return { h, x.second.get() };
        }
    }
#endif
    const auto pos = std::find_if(m_data.begin(), m_data.end(),
        [id](id_mask const & x){
        return (x.first == id) || (x.second == nullptr);
    });
    if (pos == m_data.end()) {
        //FIXME: wait until thread is released ?
        throw_error_t<thread_id_t>("too many threads");
        return { max_thread, nullptr };
    }
    if (!pos->second) { // empty slot is found
        pos->first = id;
        reset_new(pos->second, m_filesize);
        SDL_ASSERT(m_size < (int)max_size());
        ++m_size;
        SDL_TRACE("thread_insert = ", id, ", m_size = ", m_size);
    }
    const auto d = static_cast<size_t>(std::distance(m_data.begin(), pos));
    return { d, pos->second.get() };
}

bool thread_id_t::erase(id_type const id) {
#if defined(SDL_THREAD_ID_USE_HASH)
    if (use_hash) {
        const size_t h = hash_id(id);
        id_mask & x = m_data[h];
        if ((x.first == id) && (x.second != nullptr)) {
            x = {};
            SDL_ASSERT(m_size);
            --m_size;
            return true;
        }
    }
#endif
    const auto pos = std::find_if(m_data.begin(), m_data.end(),
        [id](id_mask const & x){
        return (x.first == id) && (x.second != nullptr);
    });
    if (pos != m_data.end()) {
        *pos = {};
        SDL_ASSERT(m_size);
        --m_size;
        SDL_TRACE("* thread_erase = ", id, ", m_size = ", m_size);
        return true;
    }
    SDL_ASSERT(0);
    return false;
}

#if SDL_DEBUG
namespace {
    inline constexpr uint32_t knuth_hash(uint32_t v) {
        return (v * UINT32_C(2654435761)) % thread_id_t::max_size();
    }
    class unit_test {
        void test_thread();
        void test_mask(size_t);
    public:
        unit_test() {
            static_assert(power_of<64>::value == 6, "");
            if (0) {
                test_mask(gigabyte<8>::value);
                //test_mask(terabyte<1>::value);
            }
            if (0) {
                try {
                    test_thread();
                }
                catch(sdl_exception & e) {
                    std::cout << "exception = " << e.what() << std::endl;
                }
            }
            if (0) {
            }
        }
    };
    void unit_test::test_mask(size_t const filesize) {
        thread_mask_t test(filesize);
        for (size_t i = 0; i < test.size(); ++i) {
            SDL_ASSERT(!test[i]);
            test.set_block(i);
            SDL_ASSERT(test[i]);
            if (i >= 8192)
                test.clr_block(i);
        }
        test.clr_block(test.size()-1);
        test.shrink_to_fit();
    }
    void unit_test::test_thread() {
        thread_id_t test(gigabyte<8>::value);
        auto pos = test.insert();
        SDL_ASSERT(pos.first.value() == test.insert().first.value());
        const auto id = test.get_id();
        SDL_ASSERT(test.find(id).first.value() < pool_limits::max_thread);
        SDL_ASSERT(test.find(id).second);
        SDL_ASSERT(test.erase(id));
        SDL_ASSERT(!test.erase(id));
        SDL_ASSERT(!test.find(id).second);
        SDL_TRACE_FUNCTION;
    }
    static unit_test s_test;
}
#endif //#if SDL_DEBUG
}}} // sdl

{'fraction_non_alphanumeric': 0.1651789999040215, 'fraction_numerical': 0.007582301564449563, 'mean_word_length': 1.9745932058235798, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4126698', 'n_tokens_mistral': 3694, 'n_tokens_neox': 3587, 'n_words': 654}