Skip to content

Commit

Permalink
Use std::thread/vector for cuckoo hashing
Browse files Browse the repository at this point in the history
  • Loading branch information
lenerd committed Mar 5, 2019
1 parent fb2df62 commit 76feaf0
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 22 deletions.
42 changes: 21 additions & 21 deletions src/examples/psi_phasing/common/hashing/cuckoo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/

#include <iostream>
#include <thread>
#include <vector>
#include "cuckoo.h"

//returns a cuckoo hash table with the first dimension being the bins and the second dimension being the pointer to the elements
Expand All @@ -22,11 +24,8 @@ cuckoo_hashing(uint8_t* elements, uint32_t neles, uint32_t nbins, uint32_t bitle
uint8_t* hash_table;
cuckoo_entry_ctx** cuckoo_table;
cuckoo_entry_ctx** cuckoo_stash;
cuckoo_entry_ctx* cuckoo_entries;
uint32_t i, j, stashctr=0, elebytelen;
uint32_t *perm_ptr;
pthread_t* entry_gen_tasks;
cuckoo_entry_gen_ctx* ctx;
hs_t hs;
elebytelen = ceil_divide(bitlen, 8);

Expand All @@ -42,28 +41,34 @@ cuckoo_hashing(uint8_t* elements, uint32_t neles, uint32_t nbins, uint32_t bitle
cuckoo_table = (cuckoo_entry_ctx**) calloc(nbins, sizeof(cuckoo_entry_ctx*));
cuckoo_stash = (cuckoo_entry_ctx**) calloc(maxstashsize, sizeof(cuckoo_entry_ctx*));

cuckoo_entries = (cuckoo_entry_ctx*) malloc(neles * sizeof(cuckoo_entry_ctx));
entry_gen_tasks = (pthread_t*) malloc(sizeof(pthread_t) * ntasks);
ctx = (cuckoo_entry_gen_ctx*) malloc(sizeof(cuckoo_entry_gen_ctx) * ntasks);
std::vector<cuckoo_entry_ctx> cuckoo_entries(neles);
std::vector<std::thread> entry_gen_tasks(ntasks);
std::vector<cuckoo_entry_gen_ctx> ctx(ntasks);

#ifndef TEST_UTILIZATION
for(i = 0; i < ntasks; i++) {
ctx[i].elements = elements;
ctx[i].cuckoo_entries = cuckoo_entries;
ctx[i].cuckoo_entries = cuckoo_entries.data();
ctx[i].hs = &hs;
ctx[i].startpos = i * ceil_divide(neles, ntasks);
ctx[i].endpos = std::min(ctx[i].startpos + ceil_divide(neles, ntasks), neles);
//std::cout << "Thread " << i << " starting from " << ctx[i].startpos << " going to " << ctx[i].endpos << " for " << neles << " elements" << std::endl;
if(pthread_create(entry_gen_tasks+i, NULL, gen_cuckoo_entries, (void*) (ctx+i))) {
std::cerr << "Error in creating new pthread at cuckoo hashing!" << std::endl;
exit(0);
try {
entry_gen_tasks[i] = std::thread(gen_cuckoo_entries, &ctx[i]);
} catch (const std::system_error& e) {
std::cerr << "Error in creating new thread at cuckoo hashing!\n"
<< e.what() << std::endl;
exit(1);
}
}

for(i = 0; i < ntasks; i++) {
if(pthread_join(entry_gen_tasks[i], NULL)) {
std::cerr << "Error in joining pthread at cuckoo hashing!" << std::endl;
exit(0);
try {
entry_gen_tasks[i].join();
} catch (const std::system_error& e) {
std::cerr << "Error in joining thread at cuckoo hashing!\n"
<< e.what() << std::endl;
exit(1);
}
}
#else
Expand All @@ -79,7 +84,7 @@ cuckoo_hashing(uint8_t* elements, uint32_t neles, uint32_t nbins, uint32_t bitle
//}
//insert all elements into the cuckoo hash table
for(i = 0; i < neles; i++) {
if(!(insert_element(cuckoo_table, cuckoo_entries + i, neles, hs.nhashfuns))) {
if(!(insert_element(cuckoo_table, &cuckoo_entries[i], neles, hs.nhashfuns))) {
#ifdef COUNT_FAILS
fails++;
/*std::cout << "insertion failed for element " << (hex) << (*(((uint32_t*) elements)+i)) << ", inserting to address: ";
Expand All @@ -90,7 +95,7 @@ cuckoo_hashing(uint8_t* elements, uint32_t neles, uint32_t nbins, uint32_t bitle
#else
if(stashctr < maxstashsize) {
std::cout << "Insertion not successful for element " << i <<", putting it on the stash" << std::endl;
cuckoo_stash[stashctr] = cuckoo_entries+i;
cuckoo_stash[stashctr] = &cuckoo_entries[i];
stashctr++;
} else {
std::cerr << "Stash exceeded maximum stash size of " << maxstashsize << ", terminating program" << std::endl;
Expand Down Expand Up @@ -147,11 +152,8 @@ cuckoo_hashing(uint8_t* elements, uint32_t neles, uint32_t nbins, uint32_t bitle
free(cuckoo_entries[i].address);
}
#endif
free(cuckoo_entries);
free(cuckoo_table);
free(cuckoo_stash);
free(entry_gen_tasks);
free(ctx);

free_hashing_state(&hs);

Expand All @@ -163,8 +165,7 @@ cuckoo_hashing(uint8_t* elements, uint32_t neles, uint32_t nbins, uint32_t bitle
}


void *gen_cuckoo_entries(void *ctx_void) {
cuckoo_entry_gen_ctx* ctx = (cuckoo_entry_gen_ctx*) ctx_void;
void gen_cuckoo_entries(cuckoo_entry_gen_ctx* ctx) {
hs_t* hs = ctx->hs;
uint32_t i, inbytelen = ceil_divide(hs->inbitlen, 8);
uint8_t* eleptr = ctx->elements + inbytelen * ctx->startpos;
Expand All @@ -174,7 +175,6 @@ void *gen_cuckoo_entries(void *ctx_void) {
for(i = ctx->startpos; i < ctx->endpos; i++, eleptr+=inbytelen) {
gen_cuckoo_entry(eleptr, ctx->cuckoo_entries + i, hs, i);
}
return nullptr;
}


Expand Down
2 changes: 1 addition & 1 deletion src/examples/psi_phasing/common/hashing/cuckoo.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ cuckoo_hashing(uint8_t* elements, uint32_t neles, uint32_t nbins, uint32_t bitle
uint32_t* perm, uint32_t ntasks, uint8_t** stash_elements, uint32_t maxstashsize, uint32_t** stashperm, uint32_t nhashfuns,
prf_state_ctx* prf_state);
//routine for generating the entries, is invoked by the threads
void *gen_cuckoo_entries(void *ctx);
void gen_cuckoo_entries(cuckoo_entry_gen_ctx* ctx);
inline void gen_cuckoo_entry(uint8_t* in, cuckoo_entry_ctx* out, hs_t* hs, uint32_t ele_id);
inline bool insert_element(cuckoo_entry_ctx** ctable, cuckoo_entry_ctx* element, uint32_t max_iterations, uint32_t nhashfuns);
inline uint32_t compute_stash_size(uint32_t nbins, uint32_t neles);
Expand Down

0 comments on commit 76feaf0

Please sign in to comment.