예제 #1
0
static bool supernode_is_closed_cycle(const dBNode *nlist, size_t len,
                                         BinaryKmer bkmer0, BinaryKmer bkmer1,
                                         const dBGraph *db_graph)
{
  Edges edges0, edges1;
  BinaryKmer shiftkmer;
  Nucleotide nuc;
  const size_t kmer_size = db_graph->kmer_size;

  edges0 = db_node_get_edges_union(db_graph, nlist[0].key);
  if(edges_get_indegree(edges0, nlist[0].orient) != 1) return false;

  edges1 = db_node_get_edges_union(db_graph, nlist[len-1].key);
  if(edges_get_outdegree(edges1, nlist[len-1].orient) != 1) return false;

  nuc = bkmer_get_last_nuc(bkmer0, nlist[0].orient, kmer_size);
  shiftkmer = bkmer_shift_add_last_nuc(bkmer1, nlist[len-1].orient, kmer_size, nuc);

  if(binary_kmers_are_equal(bkmer0, shiftkmer)) return true;

  shiftkmer = binary_kmer_reverse_complement(shiftkmer, kmer_size);
  return binary_kmers_are_equal(bkmer0, shiftkmer);
}
예제 #2
0
//
// Integrity checks
//
// Check an array of nodes denote a contigous path
bool db_node_check_nodes(const dBNode *nodes, size_t num,
                            const dBGraph *db_graph)
{
  if(num == 0) return true;

  const size_t kmer_size = db_graph->kmer_size;
  BinaryKmer bkmer0, bkmer1, tmp;
  Nucleotide nuc;
  size_t i;

  bkmer0 = db_node_oriented_bkmer(db_graph, nodes[0]);

  for(i = 0; i+1 < num; i++)
  {
    bkmer1 = db_node_oriented_bkmer(db_graph, nodes[i+1]);
    nuc = binary_kmer_last_nuc(bkmer1);
    tmp = binary_kmer_left_shift_add(bkmer0, kmer_size, nuc);
    ctx_assert_ret(binary_kmers_are_equal(tmp, bkmer1));
    bkmer0 = bkmer1;
  }

  return true;
}
예제 #3
0
void hash_table_empty(HashTable *const ht)
{
  size_t i;
  BinaryKmer *table = ht->table;
  for(i = 0; i < ht->capacity; i++) table[i] = unset_bkmer;
  memset(ht->buckets, 0, ht->num_of_buckets * sizeof(uint8_t[2]));

  HashTable data = {
    .table = ht->table,
    .num_of_buckets = ht->num_of_buckets,
    .hash_mask = ht->hash_mask,
    .bucket_size = ht->bucket_size,
    .capacity = ht->capacity,
    .buckets = ht->buckets,
    .num_kmers = 0,
    .collisions = {0}};

  memcpy(ht, &data, sizeof(data));
}

static inline const BinaryKmer* hash_table_find_in_bucket_mt(const HashTable *const ht,
                                                             uint_fast32_t bucket,
                                                             const BinaryKmer bkmer)
{
  const BinaryKmer *ptr = ht_bckt_ptr(ht, bucket);
  const BinaryKmer *end = ptr + *(volatile __typeof(ht->buckets[0][0])*)&ht->buckets[bucket][HT_BSIZE];

  while(ptr < end) {
    BinaryKmer tgt = *(volatile const BinaryKmer*)ptr;
    if(binary_kmers_are_equal(bkmer, tgt)) return ptr;
    ptr++;
  }
  return NULL; // Not found
}

/*
static inline
const BinaryKmer* hash_table_find_insert_in_bucket(const HashTable *const ht,
                                                   uint_fast32_t bucket,
                                                   const BinaryKmer bkmer,
                                                   bool *found)
{
  const BinaryKmer *ptr = ht_bckt_ptr(ht, bucket);
  const BinaryKmer *end = ptr + ht->buckets[bucket][HT_BSIZE];
  const BinaryKmer *empty = NULL;

  for(; ptr < end && !binary_kmers_are_equal(bkmer, *ptr); ptr++) {
    if(!HASH_ENTRY_ASSIGNED(*ptr)) empty = ptr;
  }

  *found = (ptr < end);

  if(ptr == end && empty == NULL &&
     ht->buckets[bucket][HT_BSIZE] < ht->bucket_size)
  {
    *empty = bkmer;
    ht->num_kmers++;
    ht->buckets[bucket][HT_BITEMS]++;
    ht->buckets[bucket][HT_BSIZE]++;
  }

  return ptr < end ? ptr : empty;
}

// Code to find/insert:
// h = binary_kmer_hash(key,ht->seed+i) & ht->hash_mask;
// ptr = hash_table_find_insert_in_bucket(ht, h, key, &f);
// if(ptr != NULL) {
//   *found = f;
//   return ptr;
// }
*/

// Remember to increment ht->num_kmers
static inline BinaryKmer* hash_table_insert_in_bucket(HashTable *ht,
                                                      uint_fast32_t bucket,
                                                      const BinaryKmer bkmer)
{
  ctx_assert(ht->buckets[bucket][HT_BITEMS] < ht->bucket_size);
  BinaryKmer *ptr = ht_bckt_ptr(ht, bucket);

  if(ht->buckets[bucket][HT_BSIZE] == ht->buckets[bucket][HT_BITEMS]) {
    ptr += ht->buckets[bucket][HT_BSIZE];
    ht->buckets[bucket][HT_BSIZE]++;
  }
  else {
    // Find an entry that has been deleted from this bucket previously
    while(HASH_ENTRY_ASSIGNED(*ptr)) ptr++;
  }

  *ptr = bkmer;
  ht->buckets[bucket][HT_BITEMS]++;
  return ptr;
}