void test_ahtable_sorted_iteration() { fprintf(stderr, "iterating in order through %zu keys ... \n", k); ahtable_iter_t i; ahtable_iter_begin(T, &i, true); size_t count = 0; value_t* u; value_t v; char* prev_key = malloc(m_high + 1); size_t prev_len = 0; const char *key = NULL; size_t len = 0; while (!ahtable_iter_finished(&i)) { memcpy(prev_key, key, len); prev_len = len; ++count; key = ahtable_iter_key(&i, &len); if (prev_key != NULL && cmpkey(prev_key, prev_len, key, len) > 0) { fprintf(stderr, "[error] iteration is not correctly ordered.\n"); } u = ahtable_iter_val(&i); v = str_map_get(M, key, len); if (*u != v) { if (v == 0) { fprintf(stderr, "[error] incorrect iteration (%lu, %lu)\n", *u, v); } else { fprintf(stderr, "[error] incorrect iteration tally (%lu, %lu)\n", *u, v); } } // this way we will see an error if the same key is iterated through // twice str_map_set(M, key, len, 0); ahtable_iter_next(&i); } ahtable_iter_free(&i); free(prev_key); fprintf(stderr, "done.\n"); }
void test_hattrie_iteration() { fprintf(stderr, "iterating through %zu keys ... \n", k); hattrie_iter_t* i = hattrie_iter_begin(T, false); size_t count = 0; value_t* u; value_t v; size_t len; const char* key; while (!hattrie_iter_finished(i)) { ++count; key = hattrie_iter_key(i, &len); u = hattrie_iter_val(i); v = str_map_get(M, key, len); if (*u != v) { if (v == 0) { fprintf(stderr, "[error] incorrect iteration (%lu, %lu)\n", *u, v); } else { fprintf(stderr, "[error] incorrect iteration tally (%lu, %lu)\n", *u, v); } } // this way we will see an error if the same key is iterated through // twice str_map_set(M, key, len, 0); hattrie_iter_next(i); } if (count != M->m) { fprintf(stderr, "[error] iterated through %zu element, expected %zu\n", count, M->m); } hattrie_iter_free(i); fprintf(stderr, "done.\n"); }
void test_hattrie_insert() { fprintf(stderr, "inserting %zu keys ... \n", k); size_t i, j; value_t* u; value_t v; for (j = 0; j < k; ++j) { i = rand() % n; v = 1 + str_map_get(M, xs[i], strlen(xs[i])); str_map_set(M, xs[i], strlen(xs[i]), v); u = hattrie_get(T, xs[i], strlen(xs[i])); *u += 1; if (*u != v) { fprintf(stderr, "[error] tally mismatch (reported: %lu, correct: %lu)\n", *u, v); } } fprintf(stderr, "sizeof: %zu\n", hattrie_sizeof(T)); fprintf(stderr, "deleting %zu keys ... \n", d); for (j = 0; j < d; ++j) { str_map_del(M, ds[j], strlen(ds[j])); hattrie_del(T, ds[j], strlen(ds[j])); u = hattrie_tryget(T, ds[j], strlen(ds[j])); if (u) { fprintf(stderr, "[error] item %zu still found in trie after delete\n", j); } } fprintf(stderr, "done.\n"); }
void test_ahtable_insert() { fprintf(stderr, "inserting %zu keys ... \n", k); size_t i, j; value_t* u; value_t v; for (j = 0; j < k; ++j) { i = rand() % n; v = 1 + str_map_get(M, xs[i], strlen(xs[i])); str_map_set(M, xs[i], strlen(xs[i]), v); u = ahtable_get(T, xs[i], strlen(xs[i])); *u += 1; if (*u != v) { fprintf(stderr, "[error] tally mismatch (reported: %lu, correct: %lu)\n", *u, v); } } /* delete some keys */ for (j = 0; i < k/100; ++j) { i = rand() % n; ahtable_del(T, xs[i], strlen(xs[i])); str_map_del(M, xs[i], strlen(xs[i])); u = ahtable_tryget(T, xs[i], strlen(xs[i])); if (u) { fprintf(stderr, "[error] deleted node found in ahtable\n"); } } fprintf(stderr, "done.\n"); }
void test_hattrie_sorted_iteration() { fprintf(stderr, "iterating in order through %zu keys ... \n", k); hattrie_iter_t* i = hattrie_iter_begin(T, true); size_t count = 0; value_t* u; value_t v; char* key_copy = malloc(m_high + 1); char* prev_key = malloc(m_high + 1); memset(prev_key, 0, m_high + 1); size_t prev_len = 0; const char *key = NULL; size_t len = 0; while (!hattrie_iter_finished(i)) { memcpy(prev_key, key_copy, len); prev_key[len] = '\0'; prev_len = len; ++count; key = hattrie_iter_key(i, &len); /* memory for key may be changed on iter, copy it */ strncpy(key_copy, key, len); if (prev_key != NULL && cmpkey(prev_key, prev_len, key, len) > 0) { fprintf(stderr, "[error] iteration is not correctly ordered.\n"); } u = hattrie_iter_val(i); v = str_map_get(M, key, len); if (*u != v) { if (v == 0) { fprintf(stderr, "[error] incorrect iteration (%lu, %lu)\n", *u, v); } else { fprintf(stderr, "[error] incorrect iteration tally (%lu, %lu)\n", *u, v); } } // this way we will see an error if the same key is iterated through // twice str_map_set(M, key, len, 0); hattrie_iter_next(i); } if (count != M->m) { fprintf(stderr, "[error] iterated through %zu element, expected %zu\n", count, M->m); } hattrie_iter_free(i); free(prev_key); free(key_copy); fprintf(stderr, "done.\n"); }
char *attrs_map_get(attrs_map *map, const char *name) { return str_map_get(map, name); }
bool gtf_next(gtf_file_t* f, gtf_row_t* r) { gtf_row_clear(r); if (f->state == STATE_EOF) return false; int last_k = -1; str_t* field = NULL; char* endptr; str_t* attr; while (true) { /* figure out what string we are reading into */ if (f->k != last_k) { last_k = f->k; switch (f->k) { case 0: field = r->seqname; break; case 1: field = r->source; break; case 2: field = r->feature; break; case 3: case 4: case 5: case 6: case 7: field = f->field1; break; default: break; } } /* read more, if needed */ if (*f->c == '\0') { gtf_file_refill(f); if (f->state == STATE_EOF) return false; continue; } if (*f->c == '\n') { /* skip blank lines */ if (f->state == STATE_FIELD && f->k == 0 && field->n == 0) { f->c++; f->col = 1; f->line++; } else if (f->state != STATE_KEY_SEEK && f->state != STATE_VALUE_END) { fail("Premature end of line.", f->line, f->col); } } /* handle the next character */ switch (f->state) { case STATE_FIELD: if (*f->c == '\t') { field->s[field->n] = '\0'; switch (f->k) { case 3: r->start = strtol(field->s, &endptr, 10); if (*endptr != '\0') { fail("Invalid start position.", f->line, f->col); } str_clear(field); break; case 4: r->end = strtol(field->s, &endptr, 10); if (*endptr != '\0') { fail("Invalid end position.", f->line, f->col); } str_clear(field); break; case 5: if (field->n == 1 && field->s[0] == '.') { r->score = 0.0; } else { r->score = strtod(field->s, &endptr); if (*endptr != '\0') { fail("Invalid score.", f->line, f->col); } } str_clear(field); break; case 6: if (field->n > 0 && field->s[0] == '+') { r->strand = strand_pos; } else if (field->n > 0 && field->s[0] == '-') { r->strand = strand_neg; } else { r->strand = strand_na; } str_clear(field); break; case 7: if (field->n == 1 && field->s[0] == '.') { r->frame = -1; } else { r->frame = strtol(field->s, &endptr, 10); if (*endptr != '\0') { fail("Invalid frame.", f->line, f->col); } } str_clear(field); break; default: break; } f->k++; if (f->k == 8) f->state = STATE_KEY_SEEK; } else { str_append(field, *f->c); } break; case STATE_KEY_SEEK: if (*f->c == '\n') { f->c++; goto gtf_next_finish; } if (isspace(*f->c)) break; f->state = STATE_KEY; if (*f->c == '"' || *f->c == '\'') { f->quote = *f->c; break; } else continue; case STATE_KEY: if ((f->quote != '\0' && *f->c == f->quote) || (f->quote == '\0' && isspace(*f->c))) { f->field1->s[f->field1->n] = '\0'; f->state = STATE_VALUE_SEEK; f->quote = '\0'; } else { str_append(f->field1, *f->c); } break; case STATE_VALUE_SEEK: if (isspace(*f->c)) break; f->state = STATE_VALUE; if (*f->c == '"' || *f->c == '\'') { f->quote = *f->c; break; } else continue; case STATE_VALUE: if ((*f->c == '\n') || (f->quote != '\0' && *f->c == f->quote) || (f->quote == '\0' && (*f->c == ';' || isspace(*f->c)))) { if (*f->c == '\n' && f->quote != '\0') { fail("Newline found before end quote.", f->line, f->col); } f->field2->s[f->field2->n] = '\0'; f->state = STATE_VALUE_END; attr = (str_t*)str_map_get(r->attributes, f->field1->s, f->field1->n); if (attr == NULL) { str_map_set(r->attributes, f->field1->s, f->field1->n, str_alloc()); attr = (str_t*)str_map_get(r->attributes, f->field1->s, f->field1->n); } str_copy((str_t*)attr, f->field2); str_clear(f->field1); str_clear(f->field2); if (f->quote != '\0') { f->quote = '\0'; break; } else continue; } else { str_append(f->field2, *f->c); break; } case STATE_VALUE_END: if (isspace(*f->c)) break; else if (*f->c == ';') { f->state = STATE_KEY_SEEK; break; } else if (*f->c == '\n') { f->c++; goto gtf_next_finish; } else { fail("Expected ';'.", f->line, f->col); } default: fputs("Inexplicable error in the gtf parser.\n", stderr); exit(1); } f->c++; f->col++; } gtf_next_finish: f->state = STATE_FIELD; f->k = 0; f->col = 1; f->line++; return true; }