static char * enlarge_fin_buffer(FIN * fin) { size_t r; size_t oldsize = fin->nbuffs * BUFFSZ + 1; size_t limit = (size_t) (fin->limit - fin->buff); #ifdef MSDOS /* I'm not sure this can really happen: avoid "16bit wrap" */ if (fin->nbuffs == MAX_BUFFS) { errmsg(0, "out of input buffer space"); mawk_exit(2); } #endif fin->buffp = fin->buff = (char *) zrealloc(fin->buff, oldsize, oldsize + BUFFSZ); fin->nbuffs++; r = fillbuff(fin->fd, fin->buff + (oldsize - 1), (size_t) BUFFSZ); if (r < BUFFSZ) fin->flags |= EOF_FLAG; fin->limit = fin->buff + limit + r; return fin->buff; }
Sfoff_t huffdecode(register Huff_t *hp,Sfio_t *input,Sfio_t *output,int size) { register long buffer; register int left, i, n; register int lev = 0; register unsigned char *outp; register unsigned char *inp; unsigned char *outend; unsigned char *outbuff; Sfoff_t insize = hp->outsize; /* decode the header if called with different hp */ if(lastid!=hp->id) { decode_header(hp); if(!hp->id) hp->id = id++; lastid = hp->id; } /* set up output buffers for faster access */ if(!(outp=outbuff=(unsigned char*)sfreserve(output,SF_UNBOUND,SF_LOCKR))) return(sfvalue(output)); n = sfvalue(output); if(size>=0) { if(n > size) n = size; size -= n; } outend = outp+n; /* set up input buffers for faster access */ infile = input; if(!(inp=inbuff=(unsigned char*)sfreserve(infile,SF_UNBOUND,0))) return(sfvalue(infile)); inend = inp + sfvalue(infile); buffer = hp->buffer; left = hp->left; /* main decoding loop */ while (1) { if(lev==0) { fillbuff(buffer,left,hp->maxlev,inp); i = getbits(buffer,left,CHUNK); if((n=(numbits[i]-1)) >= 0) { putbits(buffer,left,n); *outp++ = outchar[i]; goto pout; } if(hp->excess) { putbits(buffer,left,hp->excess); i >>= hp->excess; } lev = CHUNK-hp->excess; }
int printc(const char* fmt, ...) { int ret; char log_buf[LINE_MAX]; va_list ap; va_start(ap, fmt); log_buf[fillbuff(log_buf, fmt, ap)]=NUL; ret = printf("%s%s%s%s", FCOLOR, BCOLOR, log_buf, NONE); va_end(ap); return ret; }
void error_log(const char* fmt, ...) { va_list ap; char log_buf[LINE_MAX]; if(LOG_LEVEL != MC_SILENT){ printf(LOG_FMT, LOG_COLOR_RED, "[Error] - "); va_start(ap, fmt); log_buf[fillbuff(log_buf, fmt, ap)]=NUL; printf("%s", log_buf); va_end(ap); } }
static void scan_fillbuff(void) { size_t r; r = fillbuff(program_fd, (char *) buffer, (size_t) BUFFSZ); if (r < BUFFSZ) { eof_flag = 1; /* make sure eof is terminated */ buffer[r] = '\n'; buffer[r + 1] = 0; } }
void debug_log(const char* fmt, ...) { va_list ap; char log_buf[LINE_MAX]; if(LOG_LEVEL != MC_SILENT &&LOG_LEVEL != MC_ERROR_ONLY){ printf(LOG_FMT, LOG_COLOR_LIGHT_BLUE, "[Debug] - "); va_start(ap, fmt); log_buf[fillbuff(log_buf, fmt, ap)]=NUL; printf("%s", log_buf); va_end(ap); } }
void runtime_log(const char* fmt, ...) { va_list ap; char log_buf[LINE_MAX]; if(LOG_LEVEL != MC_SILENT &&LOG_LEVEL != MC_ERROR_ONLY &&LOG_LEVEL != MC_DEBUG){ printf(LOG_FMT, LOG_COLOR_DARK_GRAY, "[RTime] - "); va_start(ap, fmt); log_buf[fillbuff(log_buf, fmt, ap)]=NUL; printf("%s", log_buf); va_end(ap); } }
char * FINgets(FIN * fin, size_t *len_p) { char *p; char *q = 0; size_t match_len; size_t r; restart: if ((p = fin->buffp) >= fin->limit) { /* need a refill */ if (fin->flags & EOF_FLAG) { if (fin->flags & MAIN_FLAG) { fin = next_main(0); goto restart; } else { *len_p = 0; return (char *) 0; } } if (fin->fp) { /* line buffering */ if (!fgets(fin->buff, BUFFSZ + 1, fin->fp)) { fin->flags |= EOF_FLAG; fin->buff[0] = 0; fin->buffp = fin->buff; fin->limit = fin->buffp; goto restart; /* might be main_fin */ } else { /* return this line */ /* find eol */ p = fin->buff; while (*p != '\n' && *p != 0) p++; *p = 0; *len_p = (unsigned) (p - fin->buff); fin->buffp = p; fin->limit = fin->buffp + strlen(fin->buffp); return fin->buff; } } else { /* block buffering */ r = fillbuff(fin->fd, fin->buff, (size_t) (fin->nbuffs * BUFFSZ)); if (r == 0) { fin->flags |= EOF_FLAG; fin->buffp = fin->buff; fin->limit = fin->buffp; goto restart; /* might be main */ } else if (r < fin->nbuffs * BUFFSZ) { fin->flags |= EOF_FLAG; } fin->limit = fin->buff + r; p = fin->buffp = fin->buff; if (fin->flags & START_FLAG) { fin->flags &= ~START_FLAG; if (rs_shadow.type == SEP_MLR) { /* trim blank lines from front of file */ while (*p == '\n') p++; fin->buffp = p; if (p >= fin->limit) goto restart; } } } } retry: switch (rs_shadow.type) { case SEP_CHAR: q = memchr(p, rs_shadow.c, (size_t) (fin->limit - p)); match_len = 1; break; case SEP_STR: q = str_str(p, (size_t) (fin->limit - p), ((STRING *) rs_shadow.ptr)->str, match_len = ((STRING *) rs_shadow.ptr)->len); break; case SEP_MLR: case SEP_RE: q = re_pos_match(p, (size_t) (fin->limit - p), rs_shadow.ptr, &match_len); /* if the match is at the end, there might still be more to match in the file */ if (q && q[match_len] == 0 && !(fin->flags & EOF_FLAG)) q = (char *) 0; break; default: bozo("type of rs_shadow"); } if (q) { /* the easy and normal case */ *q = 0; *len_p = (unsigned) (q - p); fin->buffp = q + match_len; return p; } if (fin->flags & EOF_FLAG) { /* last line without a record terminator */ *len_p = r = (unsigned) (fin->limit - p); fin->buffp = p + r; if (rs_shadow.type == SEP_MLR && fin->buffp[-1] == '\n' && r != 0) { (*len_p)--; *--fin->buffp = 0; fin->limit--; } return p; } if (p == fin->buff) { /* current record is too big for the input buffer, grow buffer */ p = enlarge_fin_buffer(fin); } else { /* move a partial line to front of buffer and try again */ size_t rr; size_t amount = (size_t) (fin->limit - p); size_t blocks = fin->nbuffs * BUFFSZ; r = amount; if (blocks < r) { fin->flags |= EOF_FLAG; return 0; } p = (char *) memmove(fin->buff, p, r); q = p + r; rr = blocks - r; if ((r = fillbuff(fin->fd, q, rr)) < rr) { fin->flags |= EOF_FLAG; fin->limit = fin->buff + amount + r; } } goto retry; }
// return number of bytes written static int wal_iterate(Wal *pWal, iterate_resource *iter, u8 *buf, int bufsize, u8 *hdr, u32 *done) { // db_thread* const thr = enif_tsd_get(g_tsd_thread); #if ATOMIC db_thread *thr = g_tsd_thread; #else db_thread* thr = enif_tsd_get(g_tsd_thread); #endif mdbinf* const mdb = &thr->mdb; u32 mxPage; u64 readSafeEvnum, readSafeTerm; #ifndef _TESTAPP_ enif_mutex_lock(pWal->mtx); #endif readSafeEvnum = pWal->lastCompleteEvnum; readSafeTerm = pWal->lastCompleteTerm; mxPage = pWal->mxPage; #ifndef _TESTAPP_ enif_mutex_unlock(pWal->mtx); #endif if (!iter->started) { if (iter->evnum + iter->evterm == 0) { // If any writes come after iterator started, we must ignore those pages. iter->evnum = readSafeEvnum; iter->evterm = readSafeTerm; iter->pgnoPos = 1; iter->entiredb = 1; iter->mxPage = mxPage; if (pWal->mxPage == 0) { DBG("ERROR: Iterate on empty DB %llu",pWal->lastCompleteEvnum); *done = 1; return 0; } } else { // set mxPage to highest pgno we find. iter->pgnoPos = iter->mxPage = 0; DBG("Iterate rsterm=%llu rsevnum=%llu",readSafeTerm,readSafeEvnum); } iter->started = 1; } // send entire db (without history) if (iter->entiredb) { u32 iRead = 0; findframe(thr, pWal, iter->pgnoPos, &iRead, iter->evterm, iter->evnum, NULL, NULL); if (!iRead) { DBG("Iterate did not find page"); *done = iter->mxPage; return 0; } DBG("Iter pos=%u, mx=%u, safemx=%u",iter->pgnoPos, iter->mxPage, mxPage); if (iter->pgnoPos == iter->mxPage) *done = iter->mxPage; put8byte(hdr, iter->evterm); put8byte(hdr+sizeof(u64), iter->evnum); put4byte(hdr+sizeof(u64)*2, iter->pgnoPos); put4byte(hdr+sizeof(u64)*2+sizeof(u32), *done); iter->pgnoPos++; return fillbuff(thr, pWal, iter, buf, bufsize); } else { MDB_val logKey, logVal; int logop; u8 logKeyBuf[sizeof(u64)*3]; int rc; // ** - Log DB: {<<ActorIndex:64, Evterm:64, Evnum:64>>, <<Pgno:32/unsigned>>} memcpy(logKeyBuf, &pWal->index, sizeof(u64)); memcpy(logKeyBuf + sizeof(u64), &iter->evterm, sizeof(u64)); memcpy(logKeyBuf + sizeof(u64)*2, &iter->evnum, sizeof(u64)); logKey.mv_data = logKeyBuf; logKey.mv_size = sizeof(logKeyBuf); DBG("iterate looking for, matchterm=%llu matchevnum=%llu",iter->evterm,iter->evnum); if (mdb_cursor_get(mdb->cursorLog,&logKey,&logVal,MDB_SET) != MDB_SUCCESS) { // Evterm/evnum combination not found. Check if evnum is there. // If so return evterm. It will mean a node is in conflict. DBG("Key not found in log"); if (readSafeEvnum == iter->evnum) { iter->evterm = readSafeTerm; iter->termMismatch = 1; } else { memcpy(logKeyBuf, &pWal->index, sizeof(u64)); memcpy(logKeyBuf + sizeof(u64), &readSafeTerm, sizeof(u64)); memcpy(logKeyBuf + sizeof(u64)*2, &readSafeEvnum,sizeof(u64)); if (mdb_cursor_get(mdb->cursorLog,&logKey,&logVal,MDB_SET) != MDB_SUCCESS) { DBG("Key not found in log for undo"); *done = 1; return 0; } while (mdb_cursor_get(mdb->cursorLog,&logKey,&logVal,MDB_PREV_NODUP) == MDB_SUCCESS) { u64 aindex, term, evnum; mdb_cursor_get(mdb->cursorLog,&logKey, &logVal, MDB_GET_CURRENT); memcpy(&aindex, logKey.mv_data, sizeof(u64)); memcpy(&term, (u8*)logKey.mv_data+sizeof(u64), sizeof(u64)); memcpy(&evnum, (u8*)logKey.mv_data+sizeof(u64)*2,sizeof(u64)); DBG("Iterate on term=%llu, evnum=%llu, looking for=%llu",term,evnum,iter->evnum); if (aindex != pWal->index) break; if (iter->evnum == evnum) { iter->evterm = term; iter->termMismatch = 1; break; } } } *done = 1; return 0; } // We start iterate from next evnum not current. Input evterm/evnum is match_index and match_term. // It needs next. if (iter->started == 1 && (rc = mdb_cursor_get(mdb->cursorLog,&logKey, &logVal, MDB_NEXT_NODUP)) != MDB_SUCCESS) { *done = 1; return 0; } else { u64 aindex; rc = mdb_cursor_get(mdb->cursorLog,&logKey, &logVal, MDB_GET_CURRENT); if (rc != MDB_SUCCESS) { *done = 1; return 0; } memcpy(&aindex, (u8*)logKey.mv_data, sizeof(u64)); memcpy(&iter->evterm, (u8*)logKey.mv_data+sizeof(u64), sizeof(u64)); memcpy(&iter->evnum, (u8*)logKey.mv_data+sizeof(u64)*2,sizeof(u64)); if (aindex != pWal->index) { *done = 1; return 0; } // To keep from moving iter->evterm/iter->evnum forward more than once. iter->started = 2; } logop = MDB_FIRST_DUP; while ((rc = mdb_cursor_get(mdb->cursorLog,&logKey,&logVal,logop)) == MDB_SUCCESS) { u64 evnum,evterm; u32 pgno; u32 iRead; logop = MDB_NEXT_DUP; mdb_cursor_get(mdb->cursorLog,&logKey, &logVal, MDB_GET_CURRENT); memcpy(&pgno,logVal.mv_data,sizeof(u32)); DBG("iterate at pgno=%u, pgnopos=%u",pgno,iter->pgnoPos); if (pgno <= iter->pgnoPos) continue; findframe(thr, pWal, pgno, &iRead, iter->evterm, iter->evnum, &evterm, &evnum); if (iRead == 0) { DBG("ERROR: Did not find frame for pgno=%u, evterm=%llu, evnum=%llu", pgno, iter->evterm, iter->evnum); *done = 1; return 0; } if (evterm != iter->evterm || evnum != iter->evnum) { DBG("ERROR: Evterm/evnum does not match,looking for: evterm=%llu, evnum=%llu, " "got: evterm=%llu, evnum=%llu", iter->evterm, iter->evnum, evterm, evnum); *done = 1; return 0; } iter->pgnoPos = pgno; if ((rc = mdb_cursor_get(mdb->cursorLog,&logKey,&logVal,logop)) == MDB_SUCCESS) *done = 0; else *done = iter->pgnoPos; DBG( "logcursor get next %d, done=%u",rc,*done); put8byte(hdr, iter->evterm); put8byte(hdr+sizeof(u64), iter->evnum); put4byte(hdr+sizeof(u64)*2, iter->pgnoPos); put4byte(hdr+sizeof(u64)*2+sizeof(u32), *done); return fillbuff(thr, pWal, iter, buf, bufsize); } *done = 1; return 0; } }