void cigar_reserve(cigar_t* cig, size_t size) { if (size > cig->size) { cig->size = size; cig->ops = realloc_or_die(cig->ops, cig->size * sizeof(uint8_t)); cig->lens = realloc_or_die(cig->lens, cig->size * sizeof(uint32_t)); } }
void cigar_copy(cigar_t* dest, const cigar_t* src) { if (dest->size < src->size) { dest->size = src->size; dest->ops = realloc_or_die(dest->ops, dest->size * sizeof(uint8_t)); dest->lens = realloc_or_die(dest->lens, dest->size * sizeof(uint32_t)); } memcpy(dest->ops, src->ops, src->n * sizeof(uint8_t)); memcpy(dest->lens, src->lens, src->n * sizeof(uint32_t)); dest->n = src->n; }
void str_reserve_extra(str_t* str, size_t size) { if (str->n + size > str->size) { str->size = str->n + size; str->s = realloc_or_die(str->s, str->size * sizeof(char)); } }
void rb_ensure_space(resizable_buf b, int n) { if (b->size + n > b->allocated_size) { int new_size = b->allocated_size + max_i(rb_resize_step,b->size + n - b->allocated_size) ; b->data = (char*)realloc_or_die((void*)b->data,new_size) ; b->allocated_size = new_size ; } }
static void push_edge(edge_array_t* E, const edge_t* e) { if (E->m >= E->size) { E->size *= 2; E->es = realloc_or_die(E->es, E->size * sizeof(edge_t)); } edgecpy(&E->es[E->m++], e); }
void buffer_put(symbol c, symbol_buffer *buf){ if(buf->buffer==NULL){ buf->buffer = (symbol *)malloc_or_die(buf->size*sizeof(symbol)); } if(buf->dataLength==buf->size){ buf->size *= 2; buf->buffer = (symbol *)realloc_or_die(buf->buffer, buf->size*sizeof(symbol)); } buf->buffer[buf->dataLength++] = c; }
static uint32_t get_seq_idx(seqenc_t* E, const str_t* seqname) { uint32_t n = strmap_size(E->seq_index); uint32_t idx = strmap_get(E->seq_index, seqname); if (idx >= n) { E->d_ext_pos = realloc_or_die(E->d_ext_pos, (n + 1) * sizeof(cond_dist256_t)); cond_dist256_init(&E->d_ext_pos[n], 9 * 256); } return idx; }
static void hattrie_iter_pushchar(hattrie_iter_t* i, size_t level, char c) { if (i->keysize < level) { i->keysize *= 2; i->key = realloc_or_die(i->key, i->keysize * sizeof(char)); } if (level > 0) { i->key[level - 1] = c; } i->level = level; }
static void reserve_nmask(seqenc_t* E, size_t readlen) { if (readlen > E->nmask_n) { E->d_nmask = realloc_or_die(E->d_nmask, readlen * sizeof(dist2_t)); size_t i; for (i = E->nmask_n; i < readlen; ++i) { dist2_init(&E->d_nmask[i]); } E->nmask_n = readlen; } }
const char* hattrie_iter_key(hattrie_iter_t* i, size_t* len) { if (hattrie_iter_finished(i)) return NULL; size_t sublen; const char* subkey; if (i->has_nil_key) { subkey = NULL; sublen = 0; } else subkey = ahtable_iter_key(i->i, &sublen); if (i->keysize < i->level + sublen + 1) { while (i->keysize < i->level + sublen + 1) i->keysize *= 2; i->key = realloc_or_die(i->key, i->keysize * sizeof(char)); } memcpy(i->key + i->level, subkey, sublen); i->key[i->level + sublen] = '\0'; *len = i->level + sublen; return i->key; }
/* Push a fastq entry to back of the array. Return false if there was not enough * space. */ bool seq_array_push(seq_array_t* a, const seq_t* seq) { size_t size_needed = (seq->id1.n + 1) + (seq->seq.n + 1) + (seq->id2.n + 1) + (seq->qual.n + 1); if (size_needed > a->data_size - a->data_used) return false; if (a->n == a->size) { a->size *= 2; a->seqs = realloc_or_die(a->seqs, a->size * sizeof(seq_t)); } memcpy(&a->data[a->data_used], seq->id1.s, seq->id1.n + 1); a->seqs[a->n].id1.s = &a->data[a->data_used]; a->seqs[a->n].id1.n = seq->id1.n + 1; a->data_used += seq->id1.n + 1; memcpy(&a->data[a->data_used], seq->seq.s, seq->seq.n + 1); a->seqs[a->n].seq.s = &a->data[a->data_used]; a->seqs[a->n].seq.n = seq->seq.n + 1; a->data_used += seq->seq.n + 1; memcpy(&a->data[a->data_used], seq->id2.s, seq->id2.n + 1); a->seqs[a->n].id2.s = &a->data[a->data_used]; a->seqs[a->n].id2.n = seq->id2.n + 1; a->data_used += seq->id2.n + 1; memcpy(&a->data[a->data_used], seq->qual.s, seq->qual.n + 1); a->seqs[a->n].qual.s = &a->data[a->data_used]; a->seqs[a->n].qual.n = seq->qual.n + 1; a->data_used += seq->qual.n + 1; ++a->n; return true; }
/* malloc a buffer or die - via realloc_or_die() */ void *malloc_or_die(size_t size) { return realloc_or_die(NULL, size); }
static void str_expand(str_t* s) { s->size *= 2; realloc_or_die(s->s, s->size); memset(s->s + s->size / 2, '\0', s->size); }
segtable* add_segment (segtable* st, unspos pos1, unspos pos2, unspos length, score s, int id) { u32 newSize; size_t bytesNeeded; segment* seg, *parent; segment tempSeg; int ix, pIx; int tied, stopped; // fprintf (stderr, "add " unsposSlashSFmt " " unsposFmt " " scoreFmtSimple "; id %d\n", // pos1+1, "+", // pos2+1, ((id & rcf_rev) != 0)? "-" : "+", // length, s, id); ////////// // add the segment to the table, enlarging the table if needed, but // discarding the segment if it is low-scoring and the table has met its // coverage limit ////////// // if the table is already full and this segment scores less than the // lowest score in the table, discard it if ((st->len > 0) && (st->coverageLimit != 0) && (st->coverage >= st->coverageLimit) && (s < st->lowScore)) return st; // if there's no room for the new segment, re-allocate if (st->len >= st->size) { newSize = st->size + 100 + (st->size / 3); bytesNeeded = segtable_bytes (newSize); if (bytesNeeded > mallocLimit) goto overflow; st = (segtable*) realloc_or_die ("add_segment", st, bytesNeeded); st->size = newSize; } // add the segment, by appending it at the end seg = &st->seg[st->len++]; seg->pos1 = pos1; seg->pos2 = pos2; seg->length = length; seg->s = s; seg->id = id; seg->filter = false; seg->scoreCov = (possum) length; st->coverage += length; if ((st->len == 1) || (s < st->lowScore)) st->lowScore = s; ////////// // handle the transition between the two table states // below-the-coverage-limit: table is kept as a simple list // met-the-coverage-limit: table is kept as a proper min-heap ////////// // if this segment leaves us below the limit, we're done if ((st->coverageLimit == 0) || (st->coverage < st->coverageLimit)) return st; // if this is the first time we've reached the limit, sort the segments to // create a proper min-heap, and add the tied-score information // nota bene: if we reach here, st->coverageLimit > 0 and // st->coverage >= st->coverageLimit if (st->coverage - length < st->coverageLimit) { sort_segments (st, qSegmentsByIncreasingScore); record_tie_scores (st); #ifdef debugBinaryHeap fprintf (stderr, "\nafter sort:\n"); dump_segments (stderr, st, NULL, NULL); validate_heap (st, "after sort"); #endif // debugBinaryHeap goto prune; } ////////// // maintain the min-heap property ////////// #ifdef debugBinaryHeap //fprintf (stderr, "\nbefore percolation:\n"); //dump_segments (stderr, st, NULL, NULL); #endif // debugBinaryHeap // the rest of the list is a proper min-heap, so percolate the new segment // up the tree, while maintaining the tied-score information // nota bene: if we reach here, length >= 2 tied = false; for (ix=st->len-1 ; ix>0 ; ) { pIx = (ix-1) / 2; seg = &st->seg[ix]; parent = &st->seg[pIx]; if (seg->s >= parent->s) { tied = (seg->s == parent->s); break; } // swap this segment with its parent, and adjust old parent's tied-score // subheap tempSeg = *seg; *seg = *parent; *parent = tempSeg; record_tie_score (st, ix); ix = pIx; } record_tie_score (st, ix); // if the new segment tied an existing score, we must continue to percolate // the tied-score info up the tree if (tied) { stopped = false; for (ix=(ix-1)/2 ; ix>0 ; ix=(ix-1)/2) { if (!record_tie_score (st, ix)) { stopped = true; break; } } if (!stopped) record_tie_score (st, 0); } #ifdef debugBinaryHeap fprintf (stderr, "\nafter percolation:\n"); dump_segments (stderr, st, NULL, NULL); validate_heap (st, "after percolation"); #endif // debugBinaryHeap ////////// // remove low-scoring segments ////////// prune: // if removing the minimum scoring subheap would bring us below the // limit, no pruning is necessary if (st->coverage - st->seg[0].scoreCov < st->coverageLimit) return st; // otherwise, we must remove subheaps as long as doing so leaves us at or // above the limit while (st->coverage - st->seg[0].scoreCov >= st->coverageLimit) { s = st->seg[0].s; while (st->seg[0].s == s) { remove_root (st); #ifdef debugBinaryHeap fprintf (stderr, "\nafter a pruning:\n"); dump_segments (stderr, st, NULL, NULL); validate_heap (st, "after pruning"); #endif // debugBinaryHeap } } st->lowScore = st->seg[0].s; #ifdef debugBinaryHeap fprintf (stderr, "\nafter pruning:\n"); dump_segments (stderr, st, NULL, NULL); validate_heap (st, "after pruning"); #endif // debugBinaryHeap return st; // failure exits #define suggestions " consider using lastz_m40," \ " or setting max_malloc_index for a special build," \ " or raising scoring threshold (--hspthresh or --exact)," \ " or break your target sequence into smaller pieces" overflow: suicidef ("in add_segment()\n" "table size (%s for %s segments) exceeds allocation limit of %s;\n" suggestions, commatize(bytesNeeded), commatize(newSize), commatize(mallocLimit)); return NULL; // (doesn't get here) }
/* malloc a buffer or die - via realloc_or_die() */ void *mallocz_or_die(size_t size) { void *ptr= realloc_or_die(NULL, size); memset(ptr, 0, size); return ptr; }
void *tcp_server(void *arg) { sock_t *s = (sock_t *) arg; int i,fd,try_to_read,received; struct tcp_client *clients,*client; struct pollfd *pfds = NULL; volatile nfds_t nfds; setnonblocking(s->socket); nfds = 1; pfds = mallocz_or_die(nfds * sizeof(struct pollfd)); pfds->fd = s->socket; pfds->events = POLLIN; clients = NULL; RELAY_ATOMIC_AND( RECEIVED_STATS.active_connections, 0); int rc; for (;;) { rc = poll(pfds,nfds,CONFIG.polling_interval_ms); if (rc == -1) { if (rc == EINTR) continue; WARN_ERRNO("poll"); goto out; } for (i = 0; i < nfds; i++) { if (!pfds[i].revents) continue; if (pfds[i].fd == s->socket) { fd = accept(s->socket, NULL, NULL); if (fd == -1) { WARN_ERRNO("accept"); goto out; } setnonblocking(fd); RELAY_ATOMIC_INCREMENT( RECEIVED_STATS.active_connections, 1 ); pfds = realloc_or_die(pfds, (nfds + 1) * sizeof(*pfds)); clients = realloc_or_die(clients,(nfds + 1) * sizeof(*clients)); clients[nfds].pos = 0; clients[nfds].buf = mallocz_or_die(ASYNC_BUFFER_SIZE); // WARN("[%d] CREATE %p fd: %d",i,clients[nfds].buf,fd); pfds[nfds].fd = fd; pfds[nfds].events = POLLIN; pfds[nfds].revents = 0; nfds++; } else { client = &clients[i]; try_to_read = ASYNC_BUFFER_SIZE - client->pos; // try to read as much as possible if (try_to_read <= 0) { WARN("disconnecting, try to read: %d, pos: %d", try_to_read, client->pos); goto disconnect; } received = recv(pfds[i].fd, client->buf + client->pos, try_to_read,0); if (received <= 0) { if (received == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) continue; disconnect: shutdown(pfds[i].fd,SHUT_RDWR); close(pfds[i].fd); // WARN("[%d] DESTROY %p %d %d fd: %d vs %d",i,client->buf,client->x,i,pfds[i].fd,client->fd); free(client->buf); // shft left memcpy(pfds + i,pfds + i + 1, (nfds - i - 1) * sizeof(struct pollfd)); memcpy(clients + i,clients + i + 1, (nfds - i - 1) * sizeof(struct tcp_client)); nfds--; pfds = realloc_or_die(pfds, nfds * sizeof(struct pollfd)); clients = realloc_or_die(clients, nfds * sizeof(struct tcp_client)); RELAY_ATOMIC_DECREMENT( RECEIVED_STATS.active_connections, 1 ); continue; } client->pos += received; try_to_consume_one_more: if (client->pos < EXPECTED_HEADER_SIZE) continue; if (EXPECTED(client) > MAX_CHUNK_SIZE) { WARN("received frame (%d) > MAX_CHUNK_SIZE(%d)",EXPECTED(client),MAX_CHUNK_SIZE); goto disconnect; } if (client->pos >= EXPECTED(client) + EXPECTED_HEADER_SIZE) { buf_to_blob_enqueue(client->buf,EXPECTED(client)); client->pos -= EXPECTED(client) + EXPECTED_HEADER_SIZE; if (client->pos < 0) { WARN("BAD PACKET wrong 'next' position(< 0) pos: %d expected packet size:%d header_size: %d", client->pos, EXPECTED(client),EXPECTED_HEADER_SIZE); goto disconnect; } if (client->pos > 0) { // [ h ] [ h ] [ h ] [ h ] [ D ] [ D ] [ D ] [ h ] [ h ] [ h ] [ h ] [ D ] // ^ pos(12) // after we remove the first packet + header it becomes: // [ h ] [ h ] [ h ] [ h ] [ D ] [ D ] [ D ] [ h ] [ h ] [ h ] [ h ] [ D ] // ^ pos (5) // and then we copy from header + data, to position 0, 5 bytes // // [ h ] [ h ] [ h ] [ h ] [ D ] // ^ pos (5) memmove(client->buf, client->buf + EXPECTED_HEADER_SIZE + EXPECTED(client), client->pos); if (client->pos >= EXPECTED_HEADER_SIZE) goto try_to_consume_one_more; } } } } } out: for (i = 0; i < nfds; i++) { if (pfds[i].fd != s->socket) free(clients[i].buf); shutdown(pfds[i].fd, SHUT_RDWR); close(pfds[i].fd); } free(pfds); free(clients); set_aborted(); pthread_exit(NULL); }
static void fastq_expand_str(str_t* s) { s->size *= 2; realloc_or_die(s->s, s->size); }