Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions common/hash_table_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,27 @@ HashTableEntry::HashTableEntry(std::uint64_t value, std::size_t global_id,
global_id_ = global_id;
num_of_hash_functions_ = num_of_functions;
num_of_bins_ = num_of_bins;
has_payload_ = false;
}

HashTableEntry::HashTableEntry(std::uint64_t value, std::uint64_t payload, std::size_t global_id, std::size_t num_of_functions,
std::size_t num_of_bins) {
value_ = value;
payload_ = payload;
global_id_ = global_id;
num_of_hash_functions_ = num_of_functions;
num_of_bins_ = num_of_bins;
has_payload_ = true;
}

HashTableEntry::HashTableEntry(const HashTableEntry& other) {
num_of_hash_functions_ = other.num_of_hash_functions_;
num_of_bins_ = other.num_of_bins_;
global_id_ = other.global_id_;
has_payload_ = other.has_payload_;

value_ = other.value_;
payload_ = other.payload_;
current_function_id_ = other.current_function_id_;
possible_addresses_ = other.possible_addresses_;
}
Expand Down
8 changes: 7 additions & 1 deletion common/hash_table_entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ constexpr auto DUMMY_ELEMENT = std::numeric_limits<std::size_t>::max();

class HashTableEntry {
public:
HashTableEntry() { global_id_ = value_ = DUMMY_ELEMENT; }
HashTableEntry() { global_id_ = value_ = payload_ = DUMMY_ELEMENT; }

HashTableEntry(std::uint64_t value, std::size_t global_id, std::size_t num_of_functions,
std::size_t num_of_bins);
HashTableEntry(std::uint64_t value, std::uint64_t payload, std::size_t global_id, std::size_t num_of_functions,
std::size_t num_of_bins);
HashTableEntry(const HashTableEntry& other);

void SetCurrentAddress(std::size_t function_id) { current_function_id_ = function_id; }
Expand All @@ -62,6 +64,8 @@ class HashTableEntry {

std::uint64_t GetElement() const { return value_; }

std::uint64_t GetPayload() const { return payload_; }

void IterateFunctionNumber() {
current_function_id_ = (current_function_id_ + 1) % num_of_hash_functions_;
}
Expand All @@ -72,8 +76,10 @@ class HashTableEntry {
std::size_t num_of_hash_functions_;
std::size_t num_of_bins_;
std::size_t global_id_;
bool has_payload_;

uint64_t value_;
uint64_t payload_; //maybe check std::optional
std::size_t current_function_id_;
std::vector<std::size_t> possible_addresses_;
};
Expand Down
5 changes: 5 additions & 0 deletions common/hashing.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ class HashingTable {

virtual bool Insert(std::uint64_t element) = 0;
virtual bool Insert(const std::vector<std::uint64_t>& elements) = 0;
virtual bool Insert(const std::vector<std::uint64_t>& elements,
const std::vector<std::uint64_t>& payloads) = 0;

virtual bool Print() const = 0;

virtual std::vector<uint64_t> AsRawVector() const = 0;
virtual std::vector<uint64_t> PayloadsAsRawVector() const = 0;

virtual std::vector<std::size_t> GetNumOfElementsInBins() const = 0;

Expand All @@ -55,6 +58,7 @@ class HashingTable {
HashingTable() = default;

std::vector<std::uint64_t> elements_;
std::vector<std::uint64_t> payloads_;

// binning
double epsilon_ = 1.2f;
Expand All @@ -73,6 +77,7 @@ class HashingTable {
std::vector<std::vector<std::vector<std::uint64_t>>> luts_;

bool mapped_ = false;
bool has_payloads_ = false;

virtual bool AllocateTable() = 0;
virtual bool MapElementsToTable() = 0;
Expand Down
60 changes: 56 additions & 4 deletions cuckoo_hashing/cuckoo_hashing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ namespace ENCRYPTO {

void swap(HashTableEntry& a, HashTableEntry& b) noexcept {
std::swap(a.value_, b.value_);
std::swap(a.payload_, b.payload_);
std::swap(a.has_payload_, b.has_payload_);
std::swap(a.global_id_, b.global_id_);
std::swap(a.possible_addresses_, b.possible_addresses_);
std::swap(a.current_function_id_, b.current_function_id_);
Expand All @@ -41,11 +43,29 @@ void swap(HashTableEntry& a, HashTableEntry& b) noexcept {

bool CuckooTable::Insert(std::uint64_t element) {
elements_.push_back(element);

this->has_payloads_ = false;
return true;
}

bool CuckooTable::Insert(const std::vector<std::uint64_t>& elements) {
elements_.insert(this->elements_.end(), elements.begin(), elements.end());

this->has_payloads_ = false;
return true;
};

bool CuckooTable::Insert(const std::vector<std::uint64_t>& elements,
const std::vector<std::uint64_t>& payloads) {
if (elements.size() != payloads.size()) {
throw std::invalid_argument("num elements does not match num payloads in cuckoo insert\n"
" elements: " + std::to_string(elements.size()) + "\n"
" payloads: " + std::to_string(payloads.size()));
}
elements_.insert(this->elements_.end(), elements.begin(), elements.end());
payloads_.insert(this->payloads_.end(), payloads.begin(), payloads.end());

this->has_payloads_ = true;
return true;
};

Expand All @@ -60,15 +80,20 @@ bool CuckooTable::Print() const {
"before you print it.\n";
return false;
}
std::string payload_string = "";
if (this->has_payloads_) {
payload_string = "payload ";
}
std::cout << "Cuckoo hashing - table content "
"(the format is \"[bin#] initial_element# element_value (function#)\"):\n";
"(the format is \"[bin#] initial_element# element_value " << payload_string << "(function#)\"):\n";
for (auto i = 0ull; i < hash_table_.size(); ++i) {
const auto& entry = hash_table_.at(i);
std::string id = entry.IsEmpty() ? "" : std::to_string(entry.GetGlobalID());
std::string value = entry.IsEmpty() ? "" : std::to_string(entry.GetElement());
std::string payload = entry.IsEmpty() ? "" : std::to_string(entry.GetPayload());
std::string f = entry.IsEmpty() ? "" : std::to_string(entry.GetCurrentFunctinId());
f = std::string("(" + f + ")");
std::cout << fmt::format("[{}] {} {} {}", i, id, value, f);
std::cout << fmt::format("[{}] {} {} {} {}", i, id, value, payload, f);
}

if (stash_.size() == 0) {
Expand All @@ -90,7 +115,11 @@ bool CuckooTable::Print() const {
std::vector<uint64_t> CuckooTable::AsRawVector() const {
std::vector<uint64_t> raw_table;
raw_table.reserve(num_bins_);

// Here, the hash table function is xored to the value.
// So you might get a +-1 or 2 on your value.
// It's not an issue, because it's done on both sides, but
// it does obscure cleartext following.
// I'm not sure why they do this.
for (auto i = 0ull; i < num_bins_; ++i) {
raw_table.push_back(hash_table_.at(i).GetElement() ^
static_cast<uint64_t>(hash_table_.at(i).GetCurrentFunctinId()));
Expand All @@ -99,6 +128,20 @@ std::vector<uint64_t> CuckooTable::AsRawVector() const {
return raw_table;
}

std::vector<uint64_t> CuckooTable::PayloadsAsRawVector() const {
if (!this->HasPayloads()) {
throw std::invalid_argument("Table does not have payloads: can't return them as raw vector");
}
std::vector<uint64_t> raw_table;
raw_table.reserve(num_bins_);

for (auto i = 0ull; i < num_bins_; ++i) {
raw_table.push_back(hash_table_.at(i).GetPayload());
}

return raw_table;
}

std::vector<std::size_t> CuckooTable::GetNumOfElementsInBins() const {
std::vector<uint64_t> num_elements_in_bins(hash_table_.size(), 0);
for (auto i = 0ull; i < hash_table_.size(); ++i) {
Expand Down Expand Up @@ -141,8 +184,17 @@ bool CuckooTable::MapElementsToTable() {
GenerateLUTs();

for (auto element_id = 0ull; element_id < elements_.size(); ++element_id) {
HashTableEntry current_entry(elements_.at(element_id), element_id, num_of_hash_functions_,
// Check if it has payloads, decide what to do from there? TODO
HashTableEntry current_entry;
if (this->HasPayloads()) {
current_entry = HashTableEntry(elements_.at(element_id), payloads_.at(element_id), element_id, num_of_hash_functions_,
num_bins_);
} else {
current_entry = HashTableEntry(elements_.at(element_id), element_id, num_of_hash_functions_,
num_bins_);
}
// HashTableEntry current_entry(elements_.at(element_id), element_id, num_of_hash_functions_,
// num_bins_);

// find the new element's mappings and put them to the corresponding std::vector
auto addresses = HashToPosition(elements_.at(element_id));
Expand Down
7 changes: 6 additions & 1 deletion cuckoo_hashing/cuckoo_hashing.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace ENCRYPTO {

class HashTableEntry;

class CuckooTable : public HashingTable {
class CuckooTable final: public HashingTable {
public:
CuckooTable() = delete;

Expand All @@ -47,6 +47,8 @@ class CuckooTable : public HashingTable {
bool Insert(std::uint64_t element) final;

bool Insert(const std::vector<std::uint64_t>& elements) final;
bool Insert(const std::vector<std::uint64_t>& elements,
const std::vector<std::uint64_t>& payloads) final;

void SetRecursiveInsertionLimiter(std::size_t limiter);

Expand All @@ -56,7 +58,10 @@ class CuckooTable : public HashingTable {

auto GetStashSize() const { return stash_.size(); }

auto HasPayloads() const { return has_payloads_; }

std::vector<uint64_t> AsRawVector() const final;
std::vector<uint64_t> PayloadsAsRawVector() const final;

std::vector<std::size_t> GetNumOfElementsInBins() const final;

Expand Down
69 changes: 65 additions & 4 deletions simple_hashing/simple_hashing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,29 @@ namespace ENCRYPTO {

bool SimpleTable::Insert(std::uint64_t element) {
elements_.push_back(element);

this->has_payloads_ = false;
return true;
}

bool SimpleTable::Insert(const std::vector<std::uint64_t>& elements) {
elements_.insert(this->elements_.end(), elements.begin(), elements.end());

this->has_payloads_ = false;
return true;
}

bool SimpleTable::Insert(const std::vector<std::uint64_t>& elements,
const std::vector<std::uint64_t>& payloads) {
if (elements.size() != payloads.size()) {
throw std::invalid_argument("num elements does not match num payloads in cuckoo insert\n"
" elements: " + std::to_string(elements.size()) + "\n"
" payloads: " + std::to_string(payloads.size()));
}
elements_.insert(this->elements_.end(), elements.begin(), elements.end());
payloads_.insert(this->payloads_.end(), payloads.begin(), payloads.end());

this->has_payloads_ = true;
return true;
}

Expand All @@ -47,19 +65,24 @@ bool SimpleTable::Print() const {
"before you print it.\n";
return false;
}
std::string payload_string = "";
if (this->has_payloads_) {
payload_string = "payload ";
}
std::cout << "Simple hashing - table content "
"(the format is \"[bin#] initial_element# element_value (function#)\"):\n";
"(the format is \"[bin#] initial_element# element_value " << payload_string << "(function#)\"):\n";
for (auto bin_i = 0ull; bin_i < hash_table_.size(); ++bin_i) {
std::string bin_delimiter = bin_i == 0 ? "" : ", ";
std::cout << fmt::format("{}[{}] ", bin_delimiter, bin_i);
for (auto entry_i = 0ull; entry_i < hash_table_.at(bin_i).size(); ++entry_i) {
const auto& entry = hash_table_.at(bin_i).at(entry_i);
std::string id = entry.IsEmpty() ? "" : std::to_string(entry.GetGlobalID());
std::string value = entry.IsEmpty() ? "" : std::to_string(entry.GetElement());
std::string payload = entry.IsEmpty() ? "" : std::to_string(entry.GetPayload());
std::string delimiter = entry_i == 0 ? "" : ", ";
std::string f = entry.IsEmpty() ? "" : std::to_string(entry.GetCurrentFunctinId());
f = std::string("(" + f + ")");
std::cout << fmt::format("{}{} {} {}", delimiter, id, value, f);
std::cout << fmt::format("{}{} {} {} {}", delimiter, id, value, payload, f);
}
}

Expand Down Expand Up @@ -87,6 +110,19 @@ std::vector<uint64_t> SimpleTable::AsRawVector() const {
return raw_table;
}

std::vector<uint64_t> SimpleTable::PayloadsAsRawVector() const {
std::vector<uint64_t> raw_table;
raw_table.reserve(elements_.size());

for (auto i = 0ull; i < num_bins_; ++i) {
for (auto j = 0ull; j < hash_table_.at(i).size(); ++j) {
raw_table.push_back(hash_table_.at(i).at(j).GetPayload());
}
}

return raw_table;
}

std::vector<std::vector<uint64_t>> SimpleTable::AsRaw2DVector() const {
std::vector<std::vector<uint64_t>> raw_table(num_bins_);

Expand All @@ -101,6 +137,22 @@ std::vector<std::vector<uint64_t>> SimpleTable::AsRaw2DVector() const {
return raw_table;
}

std::vector<std::vector<uint64_t>> SimpleTable::PayloadsAsRaw2DVector() const {
if (!this->HasPayloads()) {
throw std::invalid_argument("Simple table does not have payloads, so can't return 2D vector of them");
}
std::vector<std::vector<uint64_t>> raw_table(num_bins_);

for (auto i = 0ull; i < num_bins_; ++i) {
for (auto j = 0ull; j < hash_table_.at(i).size(); ++j) {
raw_table.at(i).push_back(
hash_table_.at(i).at(j).GetPayload());
}
}

return raw_table;
}

std::vector<std::size_t> SimpleTable::GetNumOfElementsInBins() const {
std::vector<uint64_t> num_elements_in_bins(hash_table_.size(), 0);
for (auto i = 0ull; i < hash_table_.size(); ++i) {
Expand Down Expand Up @@ -153,8 +205,17 @@ bool SimpleTable::MapElementsToTable() {
GenerateLUTs();

for (auto element_id = 0ull; element_id < elements_.size(); ++element_id) {
HashTableEntry current_entry(elements_.at(element_id), element_id, num_of_hash_functions_,
num_bins_);
// Check if it has payloads, decide what to do from there? TODO
HashTableEntry current_entry;
if (this->HasPayloads()) {
current_entry = HashTableEntry(elements_.at(element_id), payloads_.at(element_id), element_id, num_of_hash_functions_,
num_bins_);
} else {
current_entry = HashTableEntry(elements_.at(element_id), element_id, num_of_hash_functions_,
num_bins_);
}
// HashTableEntry current_entry(elements_.at(element_id), element_id, num_of_hash_functions_,
// num_bins_);

// find the new element's mappings and put them to the corresponding std::vector
auto addresses = HashToPosition(elements_.at(element_id));
Expand Down
7 changes: 6 additions & 1 deletion simple_hashing/simple_hashing.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace ENCRYPTO {

class HashTableEntry;

class SimpleTable : public HashingTable {
class SimpleTable final: public HashingTable {
public:
SimpleTable() = delete;

Expand All @@ -48,6 +48,8 @@ class SimpleTable : public HashingTable {
bool Insert(std::uint64_t element) final;

bool Insert(const std::vector<std::uint64_t>& elements) final;
bool Insert(const std::vector<std::uint64_t>& elements,
const std::vector<std::uint64_t>& payloads) final;

bool Print() const final;

Expand All @@ -56,10 +58,13 @@ class SimpleTable : public HashingTable {
void SetMaximumBinSize(std::size_t size);

std::vector<uint64_t> AsRawVector() const final;
std::vector<uint64_t> PayloadsAsRawVector() const final;
std::vector<uint64_t> AsRawVectorPadded() const;
std::vector<std::vector<uint64_t>> AsRaw2DVector() const;
std::vector<std::vector<uint64_t>> PayloadsAsRaw2DVector() const;

std::vector<std::size_t> GetNumOfElementsInBins() const final;
bool HasPayloads() const { return has_payloads_; }

private:
std::vector<std::vector<HashTableEntry>> hash_table_;
Expand Down