<commit_before>#include "Table.hpp"
#include "Record.hpp"
#include "rowstore/RowStorePage.hpp"
#include "colstore/ColumnMapPage.hpp"
#include "InsertMap.hpp"

#include <commitmanager/SnapshotDescriptor.hpp>

#include <memory>

namespace tell {
namespace store {
namespace deltamain {

Table::Table(PageManager& pageManager, const Schema& schema, uint64_t /* idx */)
    : mPageManager(pageManager)
    , mRecord(schema)
    , mHashTable(crossbow::allocator::construct<CuckooTable>(pageManager))
    , mInsertLog(pageManager)
    , mUpdateLog(pageManager)
    , mPages(crossbow::allocator::construct<PageList>()),
    mNumberOfFixedSizedFields(schema.fixedSizeFields().size()),
    mNumberOfVarSizedFields(schema.varSizeFields().size())
{}

Table::~Table() {
    crossbow::allocator::destroy_now(mPages.load());

    auto ht = mHashTable.load();
    ht->destroy();
    crossbow::allocator::destroy_now(ht);
}

bool Table::get(uint64_t key,
                size_t& size,
                const char*& data,
                const commitmanager::SnapshotDescriptor& snapshot,
                uint64_t& version,
                bool& isNewest) const {
    auto ptr = mHashTable.load()->get(key);
    if (ptr) {
        CDMRecord rec(reinterpret_cast<char*>(ptr));
        bool wasDeleted;
        bool isValid;
        //TODO: in the column-map case, it might be benefitial to first ucall
        //data(.) with copyData set to false and only if !wasDeleted, call it
        //again with copyData enabled.
        data = rec.data(snapshot, size, version, isNewest, isValid, &wasDeleted);
        // if the newest version is a delete, it might be that there is
        // a new insert in the insert log
        if (isValid && !(wasDeleted && isNewest)) {
            return !wasDeleted;
        }
    }
    // in this case we need to scan through the insert log
    auto iter = mInsertLog.begin();
    auto iterEnd = mInsertLog.end();
    for (; iter != iterEnd; ++iter) {
        if (!iter->sealed()) continue;
        CDMRecord rec(iter->data());
        if (rec.isValidDataRecord() && rec.key() == key) {
            bool wasDeleted;
            bool isValid;
            data = rec.data(snapshot, size, version, isNewest, isValid, &wasDeleted);
            if (isNewest && wasDeleted) {
                // same as above, it could be that the record was inserted and
                // then updated - in this case we to continue scanning
                continue;
            }
            return !wasDeleted;
        }
    }
    // in this case the tuple does not exist
    return false;
}

void Table::insert(uint64_t key,
                   size_t size,
                   const char* const data,
                   const commitmanager::SnapshotDescriptor& snapshot,
                   bool* succeeded /*= nullptr*/) {
    // we need to get the iterator as a first step to make
    // sure to check the part of the log that was visible
    // at this point in time
    auto iter = mInsertLog.begin();
    auto ptr = mHashTable.load()->get(key);
    if (ptr) {
        // the key exists... but it could be, that it got deleted
        CDMRecord rec(reinterpret_cast<const char*>(ptr));
        bool wasDeleted, isNewest;
        bool isValid;

        uint64_t version;
        size_t s;
        rec.data(snapshot, s, version, isNewest, isValid, &wasDeleted, this, false);

        if (isValid && !(wasDeleted && isNewest)) {
            if (succeeded) *succeeded = false;<commit_msg>Get should return false if no data was found<commit_after>#include "Table.hpp"
#include "Record.hpp"
#include "rowstore/RowStorePage.hpp"
#include "colstore/ColumnMapPage.hpp"
#include "InsertMap.hpp"

#include <commitmanager/SnapshotDescriptor.hpp>

#include <memory>

namespace tell {
namespace store {
namespace deltamain {

Table::Table(PageManager& pageManager, const Schema& schema, uint64_t /* idx */)
    : mPageManager(pageManager)
    , mRecord(schema)
    , mHashTable(crossbow::allocator::construct<CuckooTable>(pageManager))
    , mInsertLog(pageManager)
    , mUpdateLog(pageManager)
    , mPages(crossbow::allocator::construct<PageList>()),
    mNumberOfFixedSizedFields(schema.fixedSizeFields().size()),
    mNumberOfVarSizedFields(schema.varSizeFields().size())
{}

Table::~Table() {
    crossbow::allocator::destroy_now(mPages.load());

    auto ht = mHashTable.load();
    ht->destroy();
    crossbow::allocator::destroy_now(ht);
}

bool Table::get(uint64_t key,
                size_t& size,
                const char*& data,
                const commitmanager::SnapshotDescriptor& snapshot,
                uint64_t& version,
                bool& isNewest) const {
    auto ptr = mHashTable.load()->get(key);
    if (ptr) {
        CDMRecord rec(reinterpret_cast<char*>(ptr));
        bool wasDeleted;
        bool isValid;
        //TODO: in the column-map case, it might be benefitial to first ucall
        //data(.) with copyData set to false and only if !wasDeleted, call it
        //again with copyData enabled.
        data = rec.data(snapshot, size, version, isNewest, isValid, &wasDeleted);
        // if the newest version is a delete, it might be that there is
        // a new insert in the insert log
        if (isValid && !(wasDeleted && isNewest)) {
            return (data != nullptr && !wasDeleted);
        }
    }
    // in this case we need to scan through the insert log
    auto iter = mInsertLog.begin();
    auto iterEnd = mInsertLog.end();
    for (; iter != iterEnd; ++iter) {
        if (!iter->sealed()) continue;
        CDMRecord rec(iter->data());
        if (rec.isValidDataRecord() && rec.key() == key) {
            bool wasDeleted;
            bool isValid;
            data = rec.data(snapshot, size, version, isNewest, isValid, &wasDeleted);
            if (isNewest && wasDeleted) {
                // same as above, it could be that the record was inserted and
                // then updated - in this case we to continue scanning
                continue;
            }
            return (data != nullptr && !wasDeleted);
        }
    }
    // in this case the tuple does not exist
    isNewest = true;
    size = 0u;
    data = nullptr;
    return false;
}

void Table::insert(uint64_t key,
                   size_t size,
                   const char* const data,
                   const commitmanager::SnapshotDescriptor& snapshot,
                   bool* succeeded /*= nullptr*/) {
    // we need to get the iterator as a first step to make
    // sure to check the part of the log that was visible
    // at this point in time
    auto iter = mInsertLog.begin();
    auto ptr = mHashTable.load()->get(key);
    if (ptr) {
        // the key exists... but it could be, that it got deleted
        CDMRecord rec(reinterpret_cast<const char*>(ptr));
        bool wasDeleted, isNewest;
        bool isValid;

        uint64_t version;
        size_t s;
        rec.data(snapshot, s, version, isNewest, isValid, &wasDeleted, this, false);

        if (isValid && !(wasDeleted && isNewest)) {
            if (succeeded) *succeeded = false;
{'fraction_non_alphanumeric': 0.11306922317778091, 'fraction_numerical': 0.0029606654448047372, 'mean_word_length': 2.3845419847328246, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 25, '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': '2598097', 'n_tokens_mistral': 2057, 'n_tokens_neox': 2042, 'n_words': 613}