/*
 * Returns true if any node in tree1 intersects with any node from tree2.
 */
int mm_trees_intersect(char *tree1, char *tree2)
{
    char *node_a, *node_b;
    
    node_a = rbtree_first(tree1);
    while (node_a) {
        node_b = rbtree_first(tree2);
        while (node_b) {
            /* Don't compare nodes to themselves */
            if (node_a == node_b) {
                node_b = rbtree_next(node_b);
                continue;
            }
            
            /* If the runs are equal they intersect */
            if (rbtree_compare_runs(node_b, node_a) == 0 ||
                rbtree_compare_runs(node_a, node_b) == 0) {
                fprintf(stderr, "(%p, %p) ", node_a, node_b);
                return !0;
            }
            node_b = rbtree_next(node_b);
        }
        node_a = rbtree_next(node_a);
    }
    
    return 0;
}
/**
 * Assemble the rrsets in the anchors, ready for use by validator.
 * @param anchors: trust anchor storage.
 * @return: false on error.
 */
static int
anchors_assemble_rrsets(struct val_anchors* anchors)
{
	struct trust_anchor* ta;
	struct trust_anchor* next;
	size_t nods, nokey;
	lock_basic_lock(&anchors->lock);
	ta=(struct trust_anchor*)rbtree_first(anchors->tree);
	while((rbnode_type*)ta != RBTREE_NULL) {
		next = (struct trust_anchor*)rbtree_next(&ta->node);
		lock_basic_lock(&ta->lock);
		if(ta->autr || (ta->numDS == 0 && ta->numDNSKEY == 0)) {
			lock_basic_unlock(&ta->lock);
			ta = next; /* skip */
			continue;
		}
		if(!anchors_assemble(ta)) {
			log_err("out of memory");
			lock_basic_unlock(&ta->lock);
			lock_basic_unlock(&anchors->lock);
			return 0;
		}
		nods = anchors_ds_unsupported(ta);
		nokey = anchors_dnskey_unsupported(ta);
		if(nods) {
			log_nametypeclass(0, "warning: unsupported "
				"algorithm for trust anchor", 
				ta->name, LDNS_RR_TYPE_DS, ta->dclass);
		}
		if(nokey) {
			log_nametypeclass(0, "warning: unsupported "
				"algorithm for trust anchor", 
				ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
		}
		if(nods == ta->numDS && nokey == ta->numDNSKEY) {
			char b[257];
			dname_str(ta->name, b);
			log_warn("trust anchor %s has no supported algorithms,"
				" the anchor is ignored (check if you need to"
				" upgrade unbound and "
#ifdef HAVE_LIBRESSL
				"libressl"
#else
				"openssl"
#endif
				")", b);
			(void)rbtree_delete(anchors->tree, &ta->node);
			lock_basic_unlock(&ta->lock);
			if(anchors->dlv_anchor == ta)
				anchors->dlv_anchor = NULL;
			anchors_delfunc(&ta->node, NULL);
			ta = next;
			continue;
		}
		lock_basic_unlock(&ta->lock);
		ta = next;
	}
	lock_basic_unlock(&anchors->lock);
	return 1;
}
/*
 * Tries to allocate a suitably sized run from the free list.
 *
 * Returns the size of the allocated run and a pointer to it.
 * Returns 0 and NULL if no suitably sized run can be found.
 */
static size_t mmrun_allocate_freerun(size_t size, char **allocated)
{
    /* Nothing to do if the free list is empty */
    if (free_runs) {
        /*
         * Scan the free list linearly for a run that is of
         * the correct size (address ordered first-fit)
         */
        int run_size;
        char *run = rbtree_first(free_runs);
        while (run && mmrun_get_largesize(run) < size) {
            run = rbtree_next(run);
        }
        
        /* If no run is found return NULL */
        if (!run) {
            *allocated = NULL;
            return 0;
        }
        
        /* Remove the run from the free list */
        rbtree_remove(run, &free_runs);
        run_size = mmrun_get_largesize(run);
        
        run_size = mmrun_split(size, run);
        
        *allocated = run;
        return run_size;
    }
    
    *allocated = NULL;
    return 0;
}
Exemple #4
0
/*****************************************************************************
 * Reads frequency attributes into the pre-allocated freqs array.
 ****************************************************************************/
static void parse_freq_attrs(PS_T *ps, const char* tag, const xmlChar **attrs) {
  int i, ncore, seen, *idx;
  char *end_ptr;
  double value, sum;
  RBNODE_T *node;
  bool seen_bad;
  ncore = rbtree_size(ps->alph_ids);
  // initilize the freqs array
  if (ps->freqs == NULL) ps->freqs = mm_malloc(sizeof(double) * ncore);
  // reset freqs array;
  for (i = 0; i < ncore; i++) ps->freqs[i] = -1;
  seen = 0;
  seen_bad = false;
  sum = 0.0;
  // iterate over attributes
  for (i = 0; attrs[i] != NULL; i += 2) {
    idx = (int*)rbtree_get(ps->alph_ids, attrs[i]);
    if (idx != NULL) {
      assert(*idx < ncore);
      if (ps->freqs[*idx] != -1) {
        dreme_attr_parse_error(ps, PARSE_ATTR_DUPLICATE, tag, (const char*)attrs[i], NULL);
        continue;
      }
      seen++;
      errno = 0; // reset because we're about to check it
      value = strtod((const char*)attrs[i+1], &end_ptr);
      // allow out of range values, mainly because freqs can be very close to zero
      if (end_ptr == (const char*)attrs[i+1] || (errno && errno != ERANGE) || value < 0 || value > 1) {
        dreme_attr_parse_error(ps, PARSE_ATTR_BAD_VALUE, tag, (const char*)attrs[i], (const char*)attrs[i+1]);
        ps->freqs[*idx] = 0; // mark frequence as seen, even though it's bad
        seen_bad = true;
        continue;
      }
      ps->freqs[*idx] = value;
      sum += value;
    }
  }
  // check we got everthing
  if (seen < ncore) {
    // identify what we're missing
    for (node = rbtree_first(ps->alph_ids); node != NULL; node = rbtree_next(node)) {
      idx = (int*)rbtree_value(node);
      if (ps->freqs[*idx] == -1) {
        dreme_attr_parse_error(ps, PARSE_ATTR_MISSING, tag, (char*)rbtree_key(node), NULL);
      }
    }
  } else if (!seen_bad) {
    // check the frequencies sum to 1
    double delta = sum - 1;
    delta = (delta < 0 ? -delta : delta);
    if (delta > (0.001 * ncore)) {
      // dreme writes background probabilities to 3 decimal places so assuming 
      // the error on each is at maximum 0.001 then the total error for the 
      // sum must be less than or equal to 0.004
      error(ps, "Probabilities of %s do not sum to 1, got %g .\n", tag, sum);
    }
  }
}
Exemple #5
0
/**************************************************************************
 * Puts counts into the spacing bins.
 **************************************************************************/
void bin_matches(int margin, int bin_size, RBTREE_T *sequences, MOTIF_T *primary_motif, SECONDARY_MOTIF_T *secondary_motif, int *matches) {
  int primary_len, secondary_len, secondary, secondary_pos, primary_rc, secondary_rc, quad, distance, max_distance;
  RBNODE_T *node;
  SECONDARY_MOTIF_T *smotif;
  SEQUENCE_T *sequence;
  SPACING_T *spacing;

  primary_len = get_motif_trimmed_length(primary_motif);

  smotif = secondary_motif;
  secondary_len = get_motif_trimmed_length(smotif->motif);

  // Note that distance counts from zero
  max_distance = margin - secondary_len;

  // for each sequence
  for (node = rbtree_first(sequences); node != NULL; node = rbtree_next(node)) {
    sequence = (SEQUENCE_T*)rbtree_value(node);
    secondary = matches[sequence->index];
    // check for a match
    if (!secondary) continue;
    // convert the encoded form into easier to use form
    primary_rc = sequence->primary_match < 0;
    secondary_rc = secondary < 0;
    secondary_pos = (secondary_rc ? -secondary : secondary);
    // calculate the distance (counts from zero) and side
    if (secondary_pos <= margin) {
      distance = margin - secondary_pos - secondary_len + 1;
      if (primary_rc) {//rotate reference direction
        quad = RIGHT;
      } else {
        quad = LEFT;
      }
    } else {
      distance = secondary_pos - margin - primary_len - 1;
      if (primary_rc) {//rotate reference direction
        quad = LEFT;
      } else {
        quad = RIGHT;
      }
    }
    // check that we're within the acceptable range
    if (distance < 0 || distance > max_distance) {
      die("Secondary motif match not within margin as it should be due to prior checks!");
    }
    // calculate the strand
    if (secondary_rc == primary_rc) {
      quad |= SAME;
    } else {
      quad |= OPPO;
    }
    // add a count to the frequencies
    spacing = smotif->spacings+(quad);
    spacing->bins[(int)(distance / bin_size)] += 1;
    smotif->total_spacings += 1;
  }
}
Exemple #6
0
static bool
_predicate (void)
{
	int i;
	KeyValuePair_t n;
	struct rbtree tree;
	KeyValuePair_t *node;
	struct rbtree_node *result;

	rbtree_init (&tree, _compareFn, 0);

	for (i = 0; i < TreeSize; i++) {
		node = malloc (sizeof (KeyValuePair_t));

		node->key = i;
		node->val = TreeSize + i;

		rbtree_insert ((struct rbtree_node *) &node->node, &tree);
	}

	// Lookup the nodes.
	for (i = 0; i < TreeSize; i++) {
		KeyValuePair_t *kvResult;
		n.key = i;
		kvResult = rbtree_container_of (rbtree_lookup ((struct rbtree_node *) &n.node, &tree), KeyValuePair_t, node);
		if (kvResult->key != i || kvResult->val != TreeSize + i) {
			return false;
		}
	}

	// This lookup should fail.
	n.key = TreeSize;
	result = rbtree_lookup ((struct rbtree_node *) &n.node, &tree);
	if (result != NULL) {
		return false;
	}

	//iterate (rbtree_first(&tree), iterateFn);
	result = rbtree_first(&tree);
	while (result) {
		KeyValuePair_t *kvResult = rbtree_container_of (result, KeyValuePair_t, node);
		struct rbtree_node *n = result;
		result = rbtree_next (result);
		rbtree_remove (n, &tree);
		free (kvResult);
	}

	// This lookup should fail because we just cleared the tree.
	n.key = TreeSize;
	n.key = 0;
	result = rbtree_lookup ((struct rbtree_node *) &n.node, &tree);
	if (result != NULL) {
		return false;
	}

	return true;
}
Exemple #7
0
tb_t *
tb_find(struct rbtree *rb, const void *tc_ptr)
{
  struct tb_t tb;
  uint16_t tc_boundaries[1] = {1};
  struct rbtree_elem *found;
  struct tb_t *ret;

  tb.num_insns = 0;
  tb.tc_boundaries = tc_boundaries;
  tb.tc_ptr = (void *)tc_ptr;
  if (!(found = rbtree_find(rb, &tb.tc_elem))) {
    return NULL;
  }
  ASSERT(   rbtree_next(found) == rbtree_end(rb)
         || tc_less(found, rbtree_next(found), NULL));
  ret = rbtree_entry(found, struct tb_t, tc_elem);
  return ret;
}
net_interface_t *net_interface_next(net_interface_t *intp)
{
    rbtree_node_t *retval;
    tree_node_t temp;

    temp.ni = intp;

    retval = rbtree_next(interface_tree, &temp.header, cmpfn);

    return ((retval) ? (((tree_node_t *) retval)->ni) : NULL);
}
static inline char *mmbin_get_available(char *bin)
{
    char *run = rbtree_first(bin);
    
    /* Bitmap will be zero for any full run */
    while (run && !mmrun_get_bitmap(run)) {
        run = rbtree_next(run);
    }
    
    return run;
}
Exemple #10
0
static void
_freeTree (struct rbtree *tree)
{
    struct rbtree_node *node = rbtree_first(tree);
    while (node)
	{
	    AddrToIndex *aiNode = rbtree_container_of (node, AddrToIndex, node);
	    node = rbtree_next (node);
	    free (aiNode);
	}
}
Exemple #11
0
//void *map_next(map_iterator *mi, pair *p) {
void *map_next(map_iterator *mi) {
    rbnode *node;

    node = rbtree_next((rbtree_iterator *)mi->iter);
    if (node == NULL) {
        return NULL;
    }
//    p->first = RBNODE_KEY(node);
//    p->second = RBNODE_VAL(node);
//    return p;
    return RBNODE_VAL(node);
//    return make_pair(RBNODE_KEY(node), RBNODE_VAL(node), NULL);
}
Exemple #12
0
/** returns true if the node is terminal so no deeper domain names exist */
static int
is_terminal(struct local_data* d)
{
	/* for empty nonterminals, the deeper domain names are sorted
	 * right after them, so simply check the next name in the tree 
	 */
	struct local_data* n = (struct local_data*)rbtree_next(&d->node);
	if(n == (struct local_data*)RBTREE_NULL)
		return 1; /* last in tree, no deeper node */
	if(dname_strict_subdomain(n->name, n->namelabs, d->name, d->namelabs))
		return 0; /* there is a deeper node */
	return 1;
}
Exemple #13
0
/***********************************************************************
 * Convert a tree of motifs into an array of motifs with a count.
 * This is intended to allow backwards compatibility with the older
 * version.
 ***********************************************************************/
void motif_tree_to_array(RBTREE_T *motif_tree, MOTIF_T **motif_array, int *num) {
  int count, i;
  MOTIF_T *motifs;
  RBNODE_T *node;

  count = rbtree_size(motif_tree);
  motifs = mm_malloc(sizeof(MOTIF_T) * count);
  for (i = 0, node = rbtree_first(motif_tree); node != NULL; i++, node = rbtree_next(node)) {
    copy_motif((MOTIF_T*)rbtree_value(node), motifs+i);
  }
  *motif_array = motifs;
  *num = count;
}
/*****************************************************************************
 * MEME > training_set > /alphabet
 * Read in the number of symbols in the alphabet and if it is nucleotide or 
 * amino-acid (RNA is apparently classed as nucleotide).
 ****************************************************************************/
void mxml_end_alphabet(void *ctx) {
  PARMSG_T *message;
  CTX_T *data;
  RBNODE_T *node;
  char *id, symbol;
  bool *exists;
  int i;

  data = (CTX_T*)ctx;
  if (data->alph == NULL) { // Custom alphabet
    alph_reader_done(data->alph_rdr);
    // report any errors that the alphabet reader found
    while (alph_reader_has_message(data->alph_rdr)) {
      message = alph_reader_next_message(data->alph_rdr);
      if (message->severity == SEVERITY_ERROR) {
        local_error(data, "Alphabet error: %s.\n", message->message);
      } else {
        local_warning(data, "Alphabet warning: %s.\n", message->message);
      }
      parmsg_destroy(message);
    }
    // try to get an alphabet
    data->alph = alph_reader_alphabet(data->alph_rdr);
    alph_reader_destroy(data->alph_rdr);
    data->alph_rdr = NULL;
  } else { // legacy alphabet
    exists = mm_malloc(sizeof(bool) * alph_size_core(data->alph));
    // set list to false
    for (i = 0; i < alph_size_core(data->alph); i++) exists[i] = false;
    // check that id's were defined for all the core alphabet symbols
    for (node = rbtree_first(data->letter_lookup); node != NULL; node = rbtree_next(node)) {
      id = (char*)rbtree_key(node);
      symbol = ((char*)rbtree_value(node))[0];
      if (exists[alph_indexc(data->alph, symbol)]) {
        // duplicate!
        local_error(data, "The letter identifier %s is not the first to refer to symbol %c.\n", id, symbol);
      }
      exists[alph_indexc(data->alph, symbol)] = true;
    }
    // now check for missing identifiers
    for (i = 0; i < alph_size_core(data->alph); i++) {
      if (!exists[i]) {
        // missing id for symbol
        local_error(data, "The symbol %c does not have an assigned identifier.\n", alph_char(data->alph, i));
      }
    }
    free(exists);
  }
}
Exemple #15
0
int
forwards_next_root(struct iter_forwards* fwd, uint16_t* dclass)
{
	struct iter_forward_zone key;
	rbnode_t* n;
	struct iter_forward_zone* p;
	if(*dclass == 0) {
		/* first root item is first item in tree */
		n = rbtree_first(fwd->tree);
		if(n == RBTREE_NULL)
			return 0;
		p = (struct iter_forward_zone*)n;
		if(dname_is_root(p->name)) {
			*dclass = p->dclass;
			return 1;
		}
		/* root not first item? search for higher items */
		*dclass = p->dclass + 1;
		return forwards_next_root(fwd, dclass);
	}
	/* find class n in tree, we may get a direct hit, or if we don't
	 * this is the last item of the previous class so rbtree_next() takes
	 * us to the next root (if any) */
	key.node.key = &key;
	key.name = (uint8_t*)"\000";
	key.namelen = 1;
	key.namelabs = 0;
	key.dclass = *dclass;
	n = NULL;
	if(rbtree_find_less_equal(fwd->tree, &key, &n)) {
		/* exact */
		return 1;
	} else {
		/* smaller element */
		if(!n || n == RBTREE_NULL)
			return 0; /* nothing found */
		n = rbtree_next(n);
		if(n == RBTREE_NULL)
			return 0; /* no higher */
		p = (struct iter_forward_zone*)n;
		if(dname_is_root(p->name)) {
			*dclass = p->dclass;
			return 1;
		}
		/* not a root node, return next higher item */
		*dclass = p->dclass+1;
		return forwards_next_root(fwd, dclass);
	}
}
/*
 * Utility function for tree visualisation.
 * Use gdb to call it.
 */
void mm_print_tree(char *tree)
{
    if (!tree) {
        printf("Empty\n");
        return;
    }
    
    char *node = rbtree_first(tree);
    while (node) {
        printf("%p ", node);
        node = rbtree_next(node);
    }
    
    printf("\n");
}
Exemple #17
0
/** iterate over the kiddies of the given name and set their parent ptr */
static void
set_kiddo_parents(struct local_zone* z, struct local_zone* match, 
	struct local_zone* newp)
{
	/* both zones and z are locked already */
	/* in the sorted rbtree, the kiddies of z are located after z */
	/* z must be present in the tree */
	struct local_zone* p = z;
	p = (struct local_zone*)rbtree_next(&p->node);
	while(p!=(struct local_zone*)RBTREE_NULL &&
		p->dclass == z->dclass && dname_strict_subdomain(p->name,
		p->namelabs, z->name, z->namelabs)) {
		/* update parent ptr */
		/* only when matches with existing parent pointer, so that
		 * deeper child structures are not touched, i.e.
		 * update of x, and a.x, b.x, f.b.x, g.b.x, c.x, y
		 * gets to update a.x, b.x and c.x */
		lock_rw_wrlock(&p->lock);
		if(p->parent == match)
			p->parent = newp;
		lock_rw_unlock(&p->lock);
		p = (struct local_zone*)rbtree_next(&p->node);
	}
}
Exemple #18
0
int router_list(struct router_t* router, int (*func)(void* param, struct node_t* node), void* param)
{
	int r = 0;
	struct rbitem_t* item;
	const struct rbtree_node_t* node;
	
	locker_lock(&router->locker);
	node = rbtree_first(&router->rbtree);
	while (node && 0 == r)
	{
		item = rbtree_entry(node, struct rbitem_t, link);
		r = func(param, item->node);
		node = rbtree_next(node);
	}
	locker_unlock(&router->locker);
	return r;
}
Exemple #19
0
/**************************************************************************
 * Calculate the total number of pvalue calculations that will be done
 * by the program. This number is used to correct the pvalues for multiple
 * tests using a bonferoni correction.
 **************************************************************************/
int calculate_test_count(int margin, int bin, int test_max, RBTREE_T *secondary_motifs) {
  int total_tests, quad_opt_count, quad_bin_count;
  SECONDARY_MOTIF_T *smotif;
  RBNODE_T *node;

  total_tests = 0;
  for (node = rbtree_first(secondary_motifs); node != NULL; node = rbtree_next(node)) {
    smotif = (SECONDARY_MOTIF_T*)rbtree_value(node);
    //the number of possible values for spacings in one quadrant
    quad_opt_count = margin - get_motif_trimmed_length(smotif->motif) + 1;
    //the number of bins in one quadrant (excluding a possible leftover bin)
    quad_bin_count = (int)(quad_opt_count / bin) + (quad_opt_count % bin ? 1 : 0);
    //add the number of tested bins
    total_tests += (test_max < quad_bin_count ? test_max : quad_bin_count) * 4;
  }
  return total_tests;
}
Exemple #20
0
void start_net_interfaces_lib(void)
{
    tree_node_t *ptr = (tree_node_t *) rbtree_first(interface_tree);

    /*
     * Now loop and start drivers.
     */
    while (ptr) {
        if (ptr->ni && ptr->ni->drv && ptr->ni->drv->start_fn(ptr->ni->unit)) {
            kerrprintf("Failed starting %s\n", ptr->ni->name);
        } else {
            kmsgprintf("Interface %s started, MTU %u\n",
                       ptr->ni->name,
                       ptr->ni->mtu);
        }
        ptr = (tree_node_t *) rbtree_next(interface_tree, &ptr->header, cmpfn);
    }
}
Exemple #21
0
/**************************************************************************
 * compute the list of ids for the most significant spacing
 **************************************************************************/
void compute_idset(int margin, int bin_size, RBTREE_T *sequences, MOTIF_T *primary_motif, SECONDARY_MOTIF_T *secondary_motif, int *matches) {
  int primary_len, secondary_len, secondary, secondary_pos, primary_rc, secondary_rc, quad, distance;
  RBNODE_T *node;
  SEQUENCE_T *sequence;

  if (secondary_motif->sig_count == 0) return;

  primary_len = get_motif_trimmed_length(primary_motif);
  secondary_len = get_motif_trimmed_length(secondary_motif->motif);

  // for each sequence
  for (node = rbtree_first(sequences); node != NULL; node = rbtree_next(node)) {
    sequence = (SEQUENCE_T*)rbtree_value(node);
    secondary = matches[sequence->index];
    // check for a match
    if (!secondary) continue;
    // convert the encoded form into easier to use form
    primary_rc = sequence->primary_match < 0;
    secondary_rc = secondary < 0;
    secondary_pos = (secondary_rc ? -secondary : secondary);
    // calculate the distance and side
    // note that distance can be zero meaning the primary is next to the secondary
    if (secondary_pos <= margin) {
      distance = margin - secondary_pos - secondary_len + 1;
      quad = LEFT;
    } else {
      distance = secondary_pos - margin - primary_len;
      quad = RIGHT;
    }
    // calculate the strand
    if (secondary_rc == primary_rc) {
      quad |= SAME;
    } else {
      quad |= OPPO;
    }
    // add the sequence id to the set if the bin matches    
    if (quad == secondary_motif->sigs->quad && (distance / bin_size) == secondary_motif->sigs->bin) {
      secondary_motif->seq_count += 1;
      secondary_motif->seqs = (int*)mm_realloc(secondary_motif->seqs, sizeof(int) * secondary_motif->seq_count);
      secondary_motif->seqs[secondary_motif->seq_count-1] = sequence->index;
    }
  }
}
Exemple #22
0
void rbtree_remove(struct rbtree_node *node, struct rbtree *tree)
{
	struct rbtree_node *parent = get_parent(node);
	struct rbtree_node *left = node->left;
	struct rbtree_node *right = node->right;
	struct rbtree_node *next;
	enum rb_color color;

	if (node == tree->first)
		tree->first = rbtree_next(node);
	if (node == tree->last)
		tree->last = rbtree_prev(node);

	if (!left)
		next = right;
	else if (!right)
		next = left;
	else
		next = get_first(right);

	if (parent)
		set_child(next, parent, parent->left == node);
	else
		tree->root = next;

	if (left && right) {
		color = get_color(next);
		set_color(get_color(node), next);

		next->left = left;
		set_parent(next, left);

		if (next != right) {
			parent = get_parent(next);
			set_parent(get_parent(node), next);

			node = next->right;
			parent->left = node;

			next->right = right;
			set_parent(next, right);
		} else {
			set_parent(parent, next);
			parent = next;
			node = next->right;
		}
	} else {
		color = get_color(node);
		node = next;
	}
	/*
	 * 'node' is now the sole successor's child and 'parent' its
	 * new parent (since the successor can have been moved).
	 */
	if (node)
		set_parent(parent, node);

	/*
	 * The 'easy' cases.
	 */
	if (color == RB_RED)
		return;
	if (node && is_red(node)) {
		set_color(RB_BLACK, node);
		return;
	}

	do {
		if (node == tree->root)
			break;

		if (node == parent->left) {
			struct rbtree_node *sibling = parent->right;

			if (is_red(sibling)) {
				set_color(RB_BLACK, sibling);
				set_color(RB_RED, parent);
				rotate_left(parent, tree);
				sibling = parent->right;
			}
			if ((!sibling->left || is_black(sibling->left))
			    && (!sibling->right || is_black(sibling->right))) {
				set_color(RB_RED, sibling);
				node = parent;
				parent = get_parent(parent);
				continue;
			}
			if (!sibling->right || is_black(sibling->right)) {
				set_color(RB_BLACK, sibling->left);
				set_color(RB_RED, sibling);
				rotate_right(sibling, tree);
				sibling = parent->right;
			}
			set_color(get_color(parent), sibling);
			set_color(RB_BLACK, parent);
			set_color(RB_BLACK, sibling->right);
			rotate_left(parent, tree);
			node = tree->root;
			break;
		} else {
			struct rbtree_node *sibling = parent->left;

			if (is_red(sibling)) {
				set_color(RB_BLACK, sibling);
				set_color(RB_RED, parent);
				rotate_right(parent, tree);
				sibling = parent->left;
			}
			if ((!sibling->left || is_black(sibling->left))
			    && (!sibling->right || is_black(sibling->right))) {
				set_color(RB_RED, sibling);
				node = parent;
				parent = get_parent(parent);
				continue;
			}
			if (!sibling->left || is_black(sibling->left)) {
				set_color(RB_BLACK, sibling->right);
				set_color(RB_RED, sibling);
				rotate_left(sibling, tree);
				sibling = parent->left;
			}
			set_color(get_color(parent), sibling);
			set_color(RB_BLACK, parent);
			set_color(RB_BLACK, sibling->left);
			rotate_right(parent, tree);
			node = tree->root;
			break;
		}
	} while (is_black(node));

	if (node)
		set_color(RB_BLACK, node);
}
Exemple #23
0
void
xfrd_write_state(struct xfrd_state* xfrd)
{
	rbnode_t* p;
	const char* statefile = xfrd->nsd->options->xfrdfile;
	FILE *out;
	time_t now = xfrd_time();

	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: write file %s", statefile));
	out = fopen(statefile, "w");
	if(!out) {
		log_msg(LOG_ERR, "xfrd: Could not open file %s for writing: %s",
				statefile, strerror(errno));
		return;
	}

	fprintf(out, "%s\n", XFRD_FILE_MAGIC);
	fprintf(out, "# This file is written on exit by nsd xfr daemon.\n");
	fprintf(out, "# This file contains slave zone information:\n");
	fprintf(out, "# 	* timeouts (when was zone data acquired)\n");
	fprintf(out, "# 	* state (OK, refreshing, expired)\n");
	fprintf(out, "# 	* which master transfer to attempt next\n");
	fprintf(out, "# The file is read on start (but not on reload) by nsd xfr daemon.\n");
	fprintf(out, "# You can edit; but do not change statement order\n");
	fprintf(out, "# and no fancy stuff (like quoted \"strings\").\n");
	fprintf(out, "#\n");
	fprintf(out, "# If you remove a zone entry, it will be refreshed.\n");
	fprintf(out, "# This can be useful for an expired zone; it revives\n");
	fprintf(out, "# the zone temporarily, from refresh-expiry time.\n");
	fprintf(out, "# If you delete the file all slave zones are updated.\n");
	fprintf(out, "#\n");
	fprintf(out, "# Note: if you edit this file while nsd is running,\n");
	fprintf(out, "#       it will be overwritten on exit by nsd.\n");
	fprintf(out, "\n");
	fprintf(out, "filetime: %lld\t# %s\n", (long long)now, ctime(&now));
	fprintf(out, "# The number of zone entries in this file\n");
	fprintf(out, "numzones: %d\n", (int)xfrd->zones->count);
	fprintf(out, "\n");
	for(p = rbtree_first(xfrd->zones); p && p!=RBTREE_NULL; p=rbtree_next(p))
	{
		xfrd_zone_t* zone = (xfrd_zone_t*)p;
		fprintf(out, "zone: \tname: %s\n", zone->apex_str);
		fprintf(out, "\tstate: %d", (int)zone->state);
		fprintf(out, " # %s", zone->state==xfrd_zone_ok?"OK":(
			zone->state==xfrd_zone_refreshing?"refreshing":"expired"));
		fprintf(out, "\n");
		fprintf(out, "\tmaster: %d\n", zone->master_num);
		fprintf(out, "\tnext_master: %d\n", zone->next_master);
		fprintf(out, "\tround_num: %d\n", zone->round_num);
		fprintf(out, "\tnext_timeout: %d",
			(zone->zone_handler_flags&EV_TIMEOUT)?(int)zone->timeout.tv_sec:0);
		if((zone->zone_handler_flags&EV_TIMEOUT)) {
			neato_timeout(out, "\t# =", zone->timeout.tv_sec);
		}
		fprintf(out, "\n");
		xfrd_write_state_soa(out, "soa_nsd", &zone->soa_nsd,
			zone->soa_nsd_acquired, zone->apex);
		xfrd_write_state_soa(out, "soa_disk", &zone->soa_disk,
			zone->soa_disk_acquired, zone->apex);
		xfrd_write_state_soa(out, "soa_notify", &zone->soa_notified,
			zone->soa_notified_acquired, zone->apex);
		fprintf(out, "\n");
	}

	fprintf(out, "%s\n", XFRD_FILE_MAGIC);
	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: written %d zones to state file",
		(int)xfrd->zones->count));
	fclose(out);
}
Exemple #24
0
int rrset_canonical_equal(struct regional* region,
	struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)
{
	struct rbtree_t sortree1, sortree2;
	struct canon_rr *rrs1, *rrs2, *p1, *p2;
	struct packed_rrset_data* d1=(struct packed_rrset_data*)k1->entry.data;
	struct packed_rrset_data* d2=(struct packed_rrset_data*)k2->entry.data;
	struct ub_packed_rrset_key fk;
	struct packed_rrset_data fd;
	size_t flen[2];
	uint8_t* fdata[2];

	/* basic compare */
	if(k1->rk.dname_len != k2->rk.dname_len ||
		k1->rk.flags != k2->rk.flags ||
		k1->rk.type != k2->rk.type ||
		k1->rk.rrset_class != k2->rk.rrset_class ||
		query_dname_compare(k1->rk.dname, k2->rk.dname) != 0)
		return 0;
	if(d1->ttl != d2->ttl ||
		d1->count != d2->count ||
		d1->rrsig_count != d2->rrsig_count ||
		d1->trust != d2->trust ||
		d1->security != d2->security)
		return 0;

	/* init */
	memset(&fk, 0, sizeof(fk));
	memset(&fd, 0, sizeof(fd));
	fk.entry.data = &fd;
	fd.count = 2;
	fd.rr_len = flen;
	fd.rr_data = fdata;
	rbtree_init(&sortree1, &canonical_tree_compare);
	rbtree_init(&sortree2, &canonical_tree_compare);
	if(d1->count > RR_COUNT_MAX || d2->count > RR_COUNT_MAX)
		return 1; /* protection against integer overflow */
	rrs1 = regional_alloc(region, sizeof(struct canon_rr)*d1->count);
	rrs2 = regional_alloc(region, sizeof(struct canon_rr)*d2->count);
	if(!rrs1 || !rrs2) return 1; /* alloc failure */

	/* sort */
	canonical_sort(k1, d1, &sortree1, rrs1);
	canonical_sort(k2, d2, &sortree2, rrs2);

	/* compare canonical-sorted RRs for canonical-equality */
	if(sortree1.count != sortree2.count)
		return 0;
	p1 = (struct canon_rr*)rbtree_first(&sortree1);
	p2 = (struct canon_rr*)rbtree_first(&sortree2);
	while(p1 != (struct canon_rr*)RBTREE_NULL &&
		p2 != (struct canon_rr*)RBTREE_NULL) {
		flen[0] = d1->rr_len[p1->rr_idx];
		flen[1] = d2->rr_len[p2->rr_idx];
		fdata[0] = d1->rr_data[p1->rr_idx];
		fdata[1] = d2->rr_data[p2->rr_idx];

		if(canonical_compare(&fk, 0, 1) != 0)
			return 0;
		p1 = (struct canon_rr*)rbtree_next(&p1->node);
		p2 = (struct canon_rr*)rbtree_next(&p2->node);
	}
	return 1;
}
/**************************************************************************
 * Dump sequence matches sorted by the name of the sequence.
 *
 * Outputs Columns:
 *   1) Trimmed lowercase sequence with uppercase matches.
 *   2) Position of the secondary match within the whole sequence.
 *   3) Sequence fragment that the primary matched.
 *   4) Strand of the primary match (+|-)
 *   5) Sequence fragment that the secondary matched.
 *   6) Strand of the secondary match (+|-)
 *   7) Is the primary match on the same strand as the secondary (s|o)
 *   8) Is the secondary match downstream or upstream (d|u)
 *   9) The gap between the primary and secondary matches
 *  10) The name of the sequence
 *  11) The p-value of the bin containing the match (adjusted for # of bins)
 *  ---if the FASTA input file sequence names are in Genome Browser format:
 *  12-14) Position of primary match in BED coordinates
 *  15) Position of primary match in Genome Browser coordinates
 *  16-18) Position of secondary match in BED coordinates
 *  19) Position of secondary match in Genome Browser coordinates
 *
 * If you wish to sort based on the gap column:
 * Sort individual output:
 *  sort -n -k 9,9 -o seqs_primary_secondary.txt seqs_primary_secondary.txt
 * Or sort all outputs:
 *  for f in seqs_*.txt; do sort -n -k 9,9 -o $f $f; done
 * Or to get just locations of primary motif in BED coordinates
 * where the secondary is on the opposite strand, upstream with a gap of 118bp:
 *   awk '$7=="o" && $8=="u" && $9==118 {print $12"\t"$13"\t"$14;}' seqs_primary_secondary.txt 
 *
 **************************************************************************/
static void dump_sequence_matches(FILE *out, int margin, int bin, 
    double sigthresh, BOOLEAN_T sig_only, RBTREE_T *sequences,
    MOTIF_T *primary_motif, SECONDARY_MOTIF_T *secondary_motif,
    ARRAY_T **matches) {
  RBNODE_T *node;
  SEQUENCE_T *sequence;
  int idx, seqlen, i, j, start, end, secondary, secondary_pos, primary_len, secondary_len, distance;
  BOOLEAN_T primary_rc, secondary_rc, downstream; 
  char *buffer, *seq, *primary_match, *secondary_match;
  ARRAY_T *secondary_array;
  ALPH_T *alph;
  // get the alphabet
  alph = get_motif_alph(primary_motif);
  // allocate a buffer for copying the trimmed sequence into and modify it
  seqlen = margin * 2 + get_motif_trimmed_length(primary_motif);
  buffer = (char*)mm_malloc(sizeof(char) * (seqlen + 1));
  // get the lengths of the motifs
  primary_len = get_motif_trimmed_length(primary_motif);
  secondary_len = get_motif_trimmed_length(secondary_motif->motif); 
  // allocate some strings for storing the matches
  primary_match = (char*)mm_malloc(sizeof(char) * (primary_len + 1));
  secondary_match = (char*)mm_malloc(sizeof(char) * (secondary_len + 1));
  // add null byte at the end of the match strings
  primary_match[primary_len] = '\0';
  secondary_match[secondary_len] = '\0';

  // iterate over all the sequences
  for (node = rbtree_first(sequences); node != NULL; node = rbtree_next(node)) {
    sequence = (SEQUENCE_T*)rbtree_value(node);
    primary_rc = get_array_item(0, sequence->primary_matches) < 0;

    //secondary = matches[sequence->index];
    secondary_array = matches[sequence->index];
    if (! secondary_array) continue;
    int n_secondary_matches = get_array_length(secondary_array);
    for (idx=0; idx<n_secondary_matches; idx++) {
      secondary = get_array_item(idx, secondary_array);
      secondary_rc = secondary < 0;
      secondary_pos = abs(secondary);

      // calculate the distance
      if (secondary_pos <= margin) {
        distance = margin - secondary_pos - secondary_len + 1;
        downstream = primary_rc;
      } else {
        distance = secondary_pos - margin - primary_len - 1;
        downstream = !primary_rc;
      }

      // copy the trimmed sequence
      seq = sequence->data;
      for (i = 0; i < seqlen; ++i) {
        buffer[i] = (alph_is_case_insensitive(alph) ? tolower(seq[i]) : seq[i]);
      }
      buffer[seqlen] = '\0';

      // uppercase primary
      start = margin;
      end = margin + primary_len;
      for (i = start, j = 0; i < end; ++i, ++j) {
        buffer[i] = (alph_is_case_insensitive(alph) ? toupper(buffer[i]) : buffer[i]);
        primary_match[j] = buffer[i];
      }

      // uppercase secondary
      // note orign was one, subtract 1 to make origin zero as required for arrays
      start = secondary_pos -1;
      end = start + secondary_len;
      for (i = start, j = 0; i < end; ++i, ++j) {
        buffer[i] = (alph_is_case_insensitive(alph) ? toupper(buffer[i]) : buffer[i]);
        secondary_match[j] = buffer[i];
      }

      // get the p-value of the seconndary match
      SPACING_T *spacings;
      if (secondary_rc == primary_rc) {
        spacings = downstream ? secondary_motif->spacings+(SAME+RIGHT) : secondary_motif->spacings+(SAME+LEFT); 
      } else {
        spacings = downstream ? secondary_motif->spacings+(OPPO+RIGHT) : secondary_motif->spacings+(OPPO+LEFT); 
      }
      double p_value = spacings->pvalue[distance/bin];

      // skip match if not significant and only reporting significant matches
      if (sig_only && (p_value > sigthresh)) continue;

      // output line to file
      fprintf(out, "%s    %3d    %s    %s    %s    %s    %s    %s    %3d    %s    %.1e", 
          buffer, 
          secondary_pos, 
          primary_match, 
          (primary_rc ? "-" : "+"), 
          secondary_match, 
          (secondary_rc ? "-" : "+"), 
          (secondary_rc == primary_rc ? "s" : "o"),
          (downstream ? "d" : "u"), 
          distance, 
          sequence->name,
          p_value
      );

      // Parse the sequence name to see if we can get genomic coordinates
      // and print additional columns with primary and secondary matches
      // in both BED and Genome Browser coordinates.
      char *chr_name;
      size_t chr_name_len;
      int start_pos, end_pos;
      if (parse_genomic_coordinates_helper(
          sequence->name,
          &chr_name,
          &chr_name_len,
          &start_pos,
          &end_pos))
      {
        // Get the start and end of the primary match in 
        // 0-relative, half-open genomic coordinates.
        int p_start = start_pos + fabs(get_array_item(0, sequence->primary_matches)) - 1;
        int p_end = p_start + primary_len;
        // Get the start and end of the secondary match in 
        // 0-relative, half-open genomic coordinates.
        int s_start, s_end;
        if ( (!primary_rc && downstream) || (primary_rc && !downstream) ) {
          s_start = p_end + distance;
          s_end = s_start + secondary_len;
        } else {
          s_end = p_start - distance;
          s_start = s_end - secondary_len;
        }
        fprintf(out, "    %s    %d    %d    %s:%d-%d", 
          chr_name, p_start, p_end, chr_name, p_start+1, p_end);
        fprintf(out, "    %s    %d    %d    %s:%d-%d\n", 
          chr_name, s_start, s_end, chr_name, s_start+1, s_end);
      } else {
        fprintf(out, "\n");
      }

    } // secondary match
  } // primary match

  free(buffer);
  free(primary_match);
  free(secondary_match);
}
Exemple #26
0
/**
 * Remove NSEC records between start and end points.
 * By walking the tree, the tree is sorted canonically.
 * @param neg: negative cache.
 * @param zone: the zone
 * @param el: element to start walking at.
 * @param nsec: the nsec record with the end point
 */
static void wipeout(struct val_neg_cache* neg, struct val_neg_zone* zone, 
	struct val_neg_data* el, struct ub_packed_rrset_key* nsec)
{
	struct packed_rrset_data* d = (struct packed_rrset_data*)nsec->
		entry.data;
	uint8_t* end;
	size_t end_len;
	int end_labs, m;
	rbnode_t* walk, *next;
	struct val_neg_data* cur;
	uint8_t buf[257];
	/* get endpoint */
	if(!d || d->count == 0 || d->rr_len[0] < 2+1)
		return;
	if(ntohs(nsec->rk.type) == LDNS_RR_TYPE_NSEC) {
		end = d->rr_data[0]+2;
		end_len = dname_valid(end, d->rr_len[0]-2);
		end_labs = dname_count_labels(end);
	} else {
		/* NSEC3 */
		if(!nsec3_get_nextowner_b32(nsec, 0, buf, sizeof(buf)))
			return;
		end = buf;
		end_labs = dname_count_size_labels(end, &end_len);
	}

	/* sanity check, both owner and end must be below the zone apex */
	if(!dname_subdomain_c(el->name, zone->name) || 
		!dname_subdomain_c(end, zone->name))
		return;

	/* detect end of zone NSEC ; wipe until the end of zone */
	if(query_dname_compare(end, zone->name) == 0) {
		end = NULL;
	}

	walk = rbtree_next(&el->node);
	while(walk && walk != RBTREE_NULL) {
		cur = (struct val_neg_data*)walk;
		/* sanity check: must be larger than start */
		if(dname_canon_lab_cmp(cur->name, cur->labs, 
			el->name, el->labs, &m) <= 0) {
			/* r == 0 skip original record. */
			/* r < 0  too small! */
			walk = rbtree_next(walk);
			continue;
		}
		/* stop at endpoint, also data at empty nonterminals must be
		 * removed (no NSECs there) so everything between 
		 * start and end */
		if(end && dname_canon_lab_cmp(cur->name, cur->labs,
			end, end_labs, &m) >= 0) {
			break;
		}
		/* this element has to be deleted, but we cannot do it
		 * now, because we are walking the tree still ... */
		/* get the next element: */
		next = rbtree_next(walk);
		/* now delete the original element, this may trigger
		 * rbtree rebalances, but really, the next element is
		 * the one we need.
		 * But it may trigger delete of other data and the
		 * entire zone. However, if that happens, this is done
		 * by deleting the *parents* of the element for deletion,
		 * and maybe also the entire zone if it is empty. 
		 * But parents are smaller in canonical compare, thus,
		 * if a larger element exists, then it is not a parent,
		 * it cannot get deleted, the zone cannot get empty.
		 * If the next==NULL, then zone can be empty. */
		if(cur->in_use)
			neg_delete_data(neg, cur);
		walk = next;
	}
}
Exemple #27
0
query_state_type
query_axfr(struct nsd *nsd, struct query *query)
{
	domain_type *closest_match;
	domain_type *closest_encloser;
	int exact;
	int added;
	uint16_t total_added = 0;

	if (query->axfr_is_done)
		return QUERY_PROCESSED;

	if (query->maxlen > AXFR_MAX_MESSAGE_LEN)
		query->maxlen = AXFR_MAX_MESSAGE_LEN;

	assert(!query_overflow(query));
	/* only keep running values for most packets */
	query->tsig_prepare_it = 0;
	query->tsig_update_it = 1;
	if(query->tsig_sign_it) {
		/* prepare for next updates */
		query->tsig_prepare_it = 1;
		query->tsig_sign_it = 0;
	}

	if (query->axfr_zone == NULL) {
		/* Start AXFR.  */
		exact = namedb_lookup(nsd->db,
				      query->qname,
				      &closest_match,
				      &closest_encloser);

		query->domain = closest_encloser;
		query->axfr_zone = domain_find_zone(closest_encloser);

		if (!exact
		    || query->axfr_zone == NULL
		    || query->axfr_zone->apex != query->domain)
		{
			/* No SOA no transfer */
			RCODE_SET(query->packet, RCODE_NOTAUTH);
			return QUERY_PROCESSED;
		}

		query->axfr_current_domain
			= (domain_type *) rbtree_first(nsd->db->domains->names_to_domains);
		query->axfr_current_rrset = NULL;
		query->axfr_current_rr = 0;
		if(query->tsig.status == TSIG_OK) {
			query->tsig_sign_it = 1; /* sign first packet in stream */
		}

		query_add_compression_domain(query, query->domain, QHEADERSZ);

		assert(query->axfr_zone->soa_rrset->rr_count == 1);
		added = packet_encode_rr(query,
					 query->axfr_zone->apex,
					 &query->axfr_zone->soa_rrset->rrs[0]);
		if (!added) {
			/* XXX: This should never happen... generate error code? */
			abort();
		}
		++total_added;
	} else {
		/*
		 * Query name and EDNS need not be repeated after the
		 * first response packet.
		 */
		query->edns.status = EDNS_NOT_PRESENT;
		buffer_set_limit(query->packet, QHEADERSZ);
		QDCOUNT_SET(query->packet, 0);
		query_prepare_response(query);
	}

	/* Add zone RRs until answer is full.  */
	assert(query->axfr_current_domain);

	while ((rbnode_t *) query->axfr_current_domain != RBTREE_NULL) {
		if (!query->axfr_current_rrset) {
			query->axfr_current_rrset = domain_find_any_rrset(
				query->axfr_current_domain,
				query->axfr_zone);
			query->axfr_current_rr = 0;
		}
		while (query->axfr_current_rrset) {
			if (query->axfr_current_rrset != query->axfr_zone->soa_rrset
			    && query->axfr_current_rrset->zone == query->axfr_zone)
			{
				while (query->axfr_current_rr < query->axfr_current_rrset->rr_count) {
					added = packet_encode_rr(
						query,
						query->axfr_current_domain,
						&query->axfr_current_rrset->rrs[query->axfr_current_rr]);
					if (!added)
						goto return_answer;
					++total_added;
					++query->axfr_current_rr;
				}
			}

			query->axfr_current_rrset = query->axfr_current_rrset->next;
			query->axfr_current_rr = 0;
		}
		assert(query->axfr_current_domain);
		query->axfr_current_domain
			= (domain_type *) rbtree_next((rbnode_t *) query->axfr_current_domain);
	}

	/* Add terminating SOA RR.  */
	assert(query->axfr_zone->soa_rrset->rr_count == 1);
	added = packet_encode_rr(query,
				 query->axfr_zone->apex,
				 &query->axfr_zone->soa_rrset->rrs[0]);
	if (added) {
		++total_added;
		query->tsig_sign_it = 1; /* sign last packet */
		query->axfr_is_done = 1;
	}

return_answer:
	AA_SET(query->packet);
	ANCOUNT_SET(query->packet, total_added);
	NSCOUNT_SET(query->packet, 0);
	ARCOUNT_SET(query->packet, 0);

	/* check if it needs tsig signatures */
	if(query->tsig.status == TSIG_OK) {
		if(query->tsig.updates_since_last_prepare >= AXFR_TSIG_SIGN_EVERY_NTH) {
			query->tsig_sign_it = 1;
		}
	}
	query_clear_compression_tables(query);
	return QUERY_IN_AXFR;
}
int main()  
{  
    int i, count = 30;  
    key_t key;  
    RBTreeNodeHandle root = NULL;  
    int test_addr = 0;

    key_t search_key = -1;
    key_t delete_key = -1;
    
    srand(1103515245);  
    for (i = 1; i < count; ++i)  
    {  
        key = rand() % count;  
        test_addr = key;

        AGILE_LOGI("key = %d", key);
        root = rbtree_insert(root, key, (void *)&test_addr);
        
        if (!(i % 188)){
            AGILE_LOGI("[i = %d] set search key %d", i, key);
            search_key = key;
        }

        if (!(i % 373)){
            AGILE_LOGI("[i = %d] set delete key %d", i, key);
            delete_key = key;
        }

        if (search_key > 0){
            if (rbtree_get(root, search_key))  
            {  
                AGILE_LOGI("[i = %d] search key %d success!", i, search_key);  
                search_key = -1;
            }  
            else  
            {  
                AGILE_LOGI("[i = %d] search key %d error!", i, search_key);  
                return (-1);  
            } 
        }
        
        if (delete_key > 0)  
        {  
            AGILE_LOGI("****** Before delete: node number: %d, repeatKeyNum: %d", rbtree_dump(root, 0), rbtree_debug_getRepeatNum());
            if (rbtree_delete(&root, delete_key) == 0)  
            {  
                AGILE_LOGI("[i = %d] delete key %d success (%d)", i, delete_key, ++deleteNum);  
                delete_key = -1;
            }  
            else  
            {  
                AGILE_LOGI("[i = %d] delete key %d error", i, delete_key);  
                return -1;
            }  
            AGILE_LOGI("****** After delete: node number: %d", rbtree_dump(root, 0));
            /*return 0;*/
        } 

        /*rbtree_dump(root, 1);*/

    }  
    
    {
        RBTreeNodeHandle n;
        i = 0;
        for (n = rbtree_first(root); n; n = rbtree_next(n)) {
            AGILE_LOGI("index %d: key - %lld", i, n->key);
            i++;
        }
    }
    return 0;  
}  
/*
 * Load background file frequencies into the array.
 */
ARRAY_T* get_file_frequencies(ALPH_T *alph, char *bg_filename, ARRAY_T *freqs) {
  regmatch_t matches[4];
  STR_T *line;
  char chunk[BG_CHUNK_SIZE+1], letter[2], *key;
  int size, terminate, offset, i;
  FILE *fp;
  regex_t bgfreq;
  double freq;
  RBTREE_T *letters;
  RBNODE_T *node;
  
  regcomp_or_die("bg freq", &bgfreq, BGFREQ_RE, REG_EXTENDED);
  letters = rbtree_create(rbtree_strcasecmp, rbtree_strcpy, free, rbtree_dblcpy, free);
  line = str_create(100);
  if (!(fp = fopen(bg_filename, "r"))) {
    die("Unable to open background file \"%s\" for reading.\n", bg_filename);
  }
  
  terminate = feof(fp);
  while (!terminate) {
    size = fread(chunk, sizeof(char), BG_CHUNK_SIZE, fp);
    chunk[size] = '\0';
    terminate = feof(fp);
    offset = 0;
    while (offset < size) {
      // skip mac newline
      if (str_len(line) == 0 && chunk[offset] == '\r') {
        offset++;
        continue;
      }
      // find next new line
      for (i = offset; i < size; ++i) {
        if (chunk[i] == '\n') break;
      }
      // append portion up to the new line or end of chunk
      str_append(line, chunk+offset, i - offset);
      // read more if we didn't find a new line
      if (i == size && !terminate) break;
      // move the offset past the new line
      offset = i + 1;
      // handle windows new line
      if (str_char(line, -1) == '\r') str_truncate(line, -1);
      // remove everything to the right of a comment character
      for (i = 0; i < str_len(line); ++i) {
        if (str_char(line, i) == '#') {
          str_truncate(line, i);
          break;
        }
      }
      // check the line for a single letter followed by a number
      if (regexec_or_die("bg freq", &bgfreq, str_internal(line), 4, matches, 0)) {
        // parse the letter and frequency value
        regex_strncpy(matches+1, str_internal(line), letter, 2);
        freq = regex_dbl(matches+2, str_internal(line));
        // check the frequency is acceptable
        if (freq < 0 || freq > 1) {
          die("The background file lists the illegal probability %g for "
            "the letter %s.\n", freq, letter);
        } else if (freq == 0) {
          die("The background file lists a probability of zero for the "
            "letter %s\n", letter);
        }
        if (freq >= 0 && freq <= 1) rbtree_put(letters, letter, &freq);
      }
      str_clear(line);
    }
  }
  // finished with the file so clean up file parsing stuff
  fclose(fp);
  str_destroy(line, FALSE);
  regfree(&bgfreq);
  // guess the alphabet
  if (*alph == INVALID_ALPH) {
    switch (rbtree_size(letters)) {
      case PROTEIN_ASIZE:
        *alph = PROTEIN_ALPH;
        break;
      case DNA_ASIZE:
        *alph = DNA_ALPH;
        break;
      default:
        die("Number of single character entries in background does not match "
            "an alphabet.\n");
    }
  }
  // make the background
  if (freqs == NULL) freqs = allocate_array(alph_size(*alph, ALL_SIZE));
  assert(get_array_length(freqs) >= alph_size(*alph, ALL_SIZE));
  init_array(-1, freqs);
  for (node = rbtree_first(letters); node != NULL; node = rbtree_next(node)) {
    key = (char*)rbtree_key(node);
    i = alph_index(*alph, key[0]);
    freq = *((double*)rbtree_value(node));
    if (i == -1) {
      die("Background contains letter %s which is not in the %s alphabet.\n", 
          key, alph_name(*alph));
    }
    if (get_array_item(i, freqs) != -1) {
      die("Background contains letter %s which has the same meaning as an "
          "already listed letter.\n", key);
    }
    set_array_item(i, freq, freqs);
  }
  // check that all items were set
  for (i = 0; i < alph_size(*alph, ALPH_SIZE); i++) {
    if (get_array_item(i, freqs) == -1) {
      die("Background is missing letter %c.\n", alph_char(*alph, i));
    }
  }
  // disabled for backwards compatability (AMA test was failing)
  //normalize_subarray(0, ALPH_ASIZE[*alph], 0.0, freqs);
  // calculate the values of the ambiguous letters from the concrete ones
  calc_ambigs(*alph, FALSE, freqs);
  // cleanup
  rbtree_destroy(letters);
  // return result
  return freqs;
}
Exemple #30
0
/** remove a random item */
static void remove_item(struct val_neg_cache* neg)
{
	int n, i;
	struct val_neg_data* d;
	rbnode_t* walk;
	struct val_neg_zone* z;
	
	lock_basic_lock(&neg->lock);
	if(neg->tree.count == 0) {
		lock_basic_unlock(&neg->lock);
		return; /* nothing to delete */
	}

	/* pick a random zone */
	walk = rbtree_first(&neg->tree); /* first highest parent, big count */
	z = (struct val_neg_zone*)walk;
	n = random() % (int)(z->count);
	if(negverbose)
		printf("neg stress delete zone %d\n", n);
	i=0;
	walk = rbtree_first(&neg->tree);
	z = (struct val_neg_zone*)walk;
	while(i!=n+1 && walk && walk != RBTREE_NULL && !z->in_use) {
		walk = rbtree_next(walk);
		z = (struct val_neg_zone*)walk;
		if(z->in_use)
			i++;
	}
	if(!walk || walk == RBTREE_NULL) {
		lock_basic_unlock(&neg->lock);
		return;
	}
	if(!z->in_use) {
		lock_basic_unlock(&neg->lock);
		return;
	}
	if(negverbose)
		log_nametypeclass(0, "delete zone", z->name, 0, 0);

	/* pick a random nsec item. - that is in use */
	walk = rbtree_first(&z->tree); /* first is highest parent */
	d = (struct val_neg_data*)walk;
	n = random() % (int)(d->count);
	if(negverbose)
		printf("neg stress delete item %d\n", n);
	i=0;
	walk = rbtree_first(&z->tree);
	d = (struct val_neg_data*)walk;
	while(i!=n+1 && walk && walk != RBTREE_NULL && !d->in_use) {
		walk = rbtree_next(walk);
		d = (struct val_neg_data*)walk;
		if(d->in_use)
			i++;
	}
	if(!walk || walk == RBTREE_NULL) {
		lock_basic_unlock(&neg->lock);
		return;
	}
	if(d->in_use) {
		if(negverbose)
			log_nametypeclass(0, "neg delete item:", d->name, 0, 0);
		neg_delete_data(neg, d);
	}
	lock_basic_unlock(&neg->lock);
}