Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
0
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;

  #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

    bitlock_yield_acquire(bktlocks, h);

    // We have the bucket lock so noone else can find or insert elements
    // therefore we can use non-threadsafe bucket functions
    // bitlock_acquire/release provide memory barriers
    ptr = hash_table_find_in_bucket_mt(ht, h, key);

    if(ptr != NULL)  {
      *found = true;
      bitlock_release(bktlocks, h);
      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);
      bitlock_release(bktlocks, h);
      __sync_add_and_fetch((volatile uint64_t*)&ht->collisions[i], 1);
      __sync_add_and_fetch((volatile uint64_t*)&ht->num_kmers, 1);
      return (hkey_t)(ptr - ht->table);
    }
    else {
      bitlock_release(bktlocks, h);
    }
  }

  rehash_error_exit(ht);
}