hkey_t hash_table_find_mt(HashTable *ht, const BinaryKmer key, volatile uint8_t *bktlocks) { const BinaryKmer *ptr; size_t i, bsize; uint_fast32_t h; for(i = 0; i < REHASH_LIMIT; i++) { h = binary_kmer_hash(key,ht->seed+i) & ht->hash_mask; bitlock_yield_acquire(bktlocks, h); ptr = hash_table_find_in_bucket(ht, h, key); if(ptr != NULL) { bitlock_release(bktlocks, h); return (hkey_t)(ptr - ht->table); } bsize = hash_table_bsize(ht, h); bitlock_release(bktlocks, h); if(bsize < ht->bucket_size) break; } return HASH_NOT_FOUND; }
hkey_t hash_table_find_or_insert_mt(HashTable *ht, const BinaryKmer key, bool *found, volatile uint8_t *bktlocks) { const BinaryKmer *ptr; size_t i; uint_fast32_t h; for(i = 0; i < REHASH_LIMIT; i++) { h = binary_kmer_hash(key,ht->seed+i) & ht->hash_mask; bitlock_yield_acquire(bktlocks, h); ptr = hash_table_find_in_bucket(ht, h, key); if(ptr != NULL) { *found = true; bitlock_release(bktlocks, h); return (hkey_t)(ptr - ht->table); } else if(hash_table_bitems(ht, h) < ht->bucket_size) { *found = false; ptr = hash_table_insert_in_bucket(ht, h, key); __sync_add_and_fetch((volatile uint64_t*)&ht->collisions[i], 1); __sync_add_and_fetch((volatile uint64_t*)&ht->num_kmers, 1); bitlock_release(bktlocks, h); return (hkey_t)(ptr - ht->table); } bitlock_release(bktlocks, h); } rehash_error_exit(ht); }
hkey_t hash_table_find(const HashTable *const ht, const BinaryKmer key) { const BinaryKmer *ptr; size_t i; uint_fast32_t h; #ifdef HASH_PREFETCH uint_fast32_t h2 = binary_kmer_hash(key,ht->seed+0) & ht->hash_mask; __builtin_prefetch(ht_bckt_ptr(ht, h2), 0, 1); #endif for(i = 0; i < REHASH_LIMIT; i++) { #ifdef HASH_PREFETCH h = h2; if(ht->buckets[h][HT_BSIZE] == ht->bucket_size) { h2 = binary_kmer_hash(key,ht->seed+i+1) & ht->hash_mask; __builtin_prefetch(ht_bckt_ptr(ht, h2), 0, 1); } #else h = binary_kmer_hash(key,ht->seed+i) & ht->hash_mask; #endif ptr = hash_table_find_in_bucket(ht, h, key); if(ptr != NULL) return (hkey_t)(ptr - ht->table); if(ht->buckets[h][HT_BSIZE] < ht->bucket_size) break; } return HASH_NOT_FOUND; }
Element * hash_table_find(Key key, HashTable * hash_table) { if (hash_table == NULL) { die("hash_table_find has been called with a NULL table! Exiting"); } Element * ret = NULL; long long current_pos; boolean overflow; int rehash = 0; boolean found; do { found = hash_table_find_in_bucket(key,¤t_pos, &overflow, hash_table,rehash); if (found) //then we know overflow is false - this is checked in find_in_bucket { ret = &hash_table->table[current_pos]; } else if (overflow) { //rehash rehash++; if (rehash>hash_table->max_rehash_tries) { //fprintf(stderr,"too much rehashing!! Rehash=%d\n", rehash); // die("Dear user - you have not allocated enough memory to contain your sequence data. Either allocate more memory (have you done your calculations right? have you allowed for sequencing errors?), or threshold more harshly on quality score, and try again. Aborting mission.\n"); } } } while(overflow); return ret; }
Element * hash_table_find_or_insert(Key key, boolean * found, HashTable * hash_table){ if (hash_table == NULL) { die("NULL table!"); } Element element; Element * ret = NULL; int rehash = 0; boolean overflow; long long current_pos; do{ *found = hash_table_find_in_bucket(key,¤t_pos,&overflow,hash_table,rehash); if (! *found) { if (!overflow) //it is definitely nowhere in the hashtable, so free to insert { //sanity check if (!db_node_check_for_flag_ALL_OFF(&hash_table->table[current_pos])) { die("error trying to write on an occupied element\n"); } //insert element //printf("Inserting element at position %qd in bucket \n", current_pos); element_initialise(&element,key, hash_table->kmer_size); //hash_table->table[current_pos] = element; //structure assignment element_assign(&(hash_table->table[current_pos]) , &element); ret = &hash_table->table[current_pos]; hash_table->unique_kmers++; } else { //overflow -> rehashing rehash++; if (rehash>hash_table->max_rehash_tries) { //fprintf(stderr,"too much rehashing!! Reserve more memory. Rehash=%d\n", rehash); die("Dear user - you have not allocated enough memory to contain your sequence data. Either allocate more memory (have you done your calculations right? have you allowed for sequencing errors?), or threshold more harshly on quality score, and try again. Aborting mission.\n"); } } } else //it is found { ret = &hash_table->table[current_pos]; } } while (overflow); hash_table->collisions[rehash]++; return ret; }
//currently not used, and must add a test boolean hash_table_apply_or_insert(Key key, void (*f)(Element *), HashTable * hash_table){ if (hash_table == NULL) { puts("NULL table!"); exit(1); } long long current_pos; Element element; boolean overflow; int rehash=0; boolean found; do { found = hash_table_find_in_bucket(key,¤t_pos,&overflow, hash_table,rehash); if (!found) { if (!overflow) { //sanity check if (!element_check_for_flag_ALL_OFF(&hash_table->table[current_pos])){ printf("Out of bounds - trying to insert new node beyond end of bucket\n"); exit(1); } element_initialise(&element,key, hash_table->kmer_size); element_assign( &(hash_table->table[current_pos]), &element); hash_table->unique_kmers++; } else//overflow { rehash++; if (rehash>hash_table->max_rehash_tries) { fprintf(stderr,"too much rehashing!! Rehash=%d\n", rehash); exit(1); } } } else { f(&hash_table->table[current_pos]); } }while(overflow); return found; }
boolean hash_table_apply_or_insert(Key key, void (*f)(Element *), HashTable * hash_table){ if (hash_table == NULL) { die("NULL table!"); } long long current_pos; Element element; boolean overflow; int rehash=0; boolean found; do { found = hash_table_find_in_bucket(key,¤t_pos,&overflow, hash_table,rehash); if (!found) { if (!overflow) { //sanity check if (!db_node_check_for_flag_ALL_OFF(&hash_table->table[current_pos])){ die("Out of bounds - trying to insert new node beyond end of bucket\n"); } element_initialise(&element,key, hash_table->kmer_size); element_assign( &(hash_table->table[current_pos]), &element); hash_table->unique_kmers++; } else//overflow { rehash++; if (rehash>hash_table->max_rehash_tries) { die("Dear user - you have not allocated enough memory to contain your sequence data. \n" "Either allocate more memory (have you done your calculations right?\n" "Have you allowed for sequencing errors?), or threshold more harshly on\n" "quality score, and try again. Aborting mission.\n"); } } } else { f(&hash_table->table[current_pos]); } }while(overflow); return found; }
hkey_t hash_table_find_or_insert(HashTable *ht, const BinaryKmer key, bool *found) { const BinaryKmer *ptr; size_t i; uint_fast32_t h; #ifdef HASH_PREFETCH uint_fast32_t h2 = binary_kmer_hash(key,ht->seed+0) & ht->hash_mask; __builtin_prefetch(ht_bckt_ptr(ht, h2), 0, 1); #endif for(i = 0; i < REHASH_LIMIT; i++) { #ifdef HASH_PREFETCH h = h2; if(ht->buckets[h][HT_BSIZE] == ht->bucket_size) { h2 = binary_kmer_hash(key,ht->seed+i+1) & ht->hash_mask; __builtin_prefetch(ht_bckt_ptr(ht, h2), 0, 1); } #else h = binary_kmer_hash(key,ht->seed+i) & ht->hash_mask; #endif ptr = hash_table_find_in_bucket(ht, h, key); if(ptr != NULL) { *found = true; return (hkey_t)(ptr - ht->table); } else if(ht->buckets[h][HT_BITEMS] < ht->bucket_size) { *found = false; ptr = hash_table_insert_in_bucket(ht, h, key); ht->collisions[i]++; // only increment collisions when inserting ht->num_kmers++; return (hkey_t)(ptr - ht->table); } } rehash_error_exit(ht); }