Ejemplo n.º 1
0
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_mt(ht, h, key);
    if(ptr != NULL) return (hkey_t)(ptr - ht->table);
    if(ht->buckets[h][HT_BSIZE] < ht->bucket_size) return HASH_NOT_FOUND;
  }

  rehash_error_exit(ht);
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 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);
}
Ejemplo n.º 4
0
// This methods inserts an element in the next available bucket
// It doesn't check whether another element with the same key is present in the
// table used for fast loading when it is known that all the elements in the
// input have different key
hkey_t hash_table_insert(HashTable *const ht, const BinaryKmer key)
{
  const BinaryKmer *ptr;
  size_t i;
  uint_fast32_t h;
  // prefetch doesn't make sense when not searching..

  for(i = 0; i < REHASH_LIMIT; i++)
  {
    h = binary_kmer_hash(key,ht->seed+i) & ht->hash_mask;
    if(ht->buckets[h][HT_BITEMS] < ht->bucket_size) {
      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);
}
Ejemplo n.º 5
0
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_mt(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);
}