/* * 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; }
/***************************************************************************** * 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); } } }
/************************************************************************** * 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; } }
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; }
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; }
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); } }
//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); }
/** 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; }
/*********************************************************************** * 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); } }
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"); }
/** 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); } }
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; }
/************************************************************************** * 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; }
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); } }
/************************************************************************** * 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; } } }
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); }
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); }
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); }
/** * 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; } }
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; }
/** 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); }