Changeset: 254dcf085ee5 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/254dcf085ee5 Modified Files: gdk/gdk_bbp.c Branch: Jul2021 Log Message:
Refactor BBP.dir reading code. Use a function to read a single line. This function is now also used for the TAILCHKMASK check just before the actual commit. Manual backport of changeset 11d1a723b150. diffs (truncated from 786 to 300 lines): diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c --- a/gdk/gdk_bbp.c +++ b/gdk/gdk_bbp.c @@ -428,7 +428,7 @@ static gdk_return BBPrecover_subdir(void static bool BBPdiskscan(const char *, size_t); static int -heapinit(BAT *b, const char *buf, int *hashash, unsigned bbpversion, bat bid, const char *filename, int lineno) +heapinit(BAT *b, const char *buf, int *hashash, unsigned bbpversion, const char *filename, int lineno) { int t; char type[33]; @@ -488,7 +488,7 @@ heapinit(BAT *b, const char *buf, int *h return -1; } } else if (var != (t == TYPE_void || BATatoms[t].atomPut != NULL)) { - TRC_CRITICAL(GDK, "inconsistent entry in BBP.dir: tvarsized mismatch for BAT %d on line %d\n", (int) bid, lineno); + TRC_CRITICAL(GDK, "inconsistent entry in BBP.dir: tvarsized mismatch for BAT %d on line %d\n", (int) b->batCacheid, lineno); return -1; } else if (var && t != 0 ? ATOMsize(t) < width || @@ -498,7 +498,7 @@ heapinit(BAT *b, const char *buf, int *h #endif ) : ATOMsize(t) != width) { - TRC_CRITICAL(GDK, "inconsistent entry in BBP.dir: tsize mismatch for BAT %d on line %d\n", (int) bid, lineno); + TRC_CRITICAL(GDK, "inconsistent entry in BBP.dir: tsize mismatch for BAT %d on line %d\n", (int) b->batCacheid, lineno); return -1; } b->ttype = t; @@ -541,7 +541,7 @@ heapinit(BAT *b, const char *buf, int *h } static int -vheapinit(BAT *b, const char *buf, int hashash, bat bid, const char *filename, int lineno) +vheapinit(BAT *b, const char *buf, int hashash, const char *filename, int lineno) { int n = 0; uint64_t free, size; @@ -555,11 +555,6 @@ vheapinit(BAT *b, const char *buf, int h TRC_CRITICAL(GDK, "invalid format for BBP.dir on line %d", lineno); return -1; } - b->tvheap = GDKmalloc(sizeof(Heap)); - if (b->tvheap == NULL) { - TRC_CRITICAL(GDK, "cannot allocate memory for heap."); - return -1; - } if (b->ttype >= 0 && ATOMstorage(b->ttype) == TYPE_str && free < GDK_STRHASHTABLE * sizeof(stridx_t) + BATTINY * GDK_VARALIGN) @@ -577,108 +572,216 @@ vheapinit(BAT *b, const char *buf, int h .cleanhash = true, .newstorage = STORE_INVALID, .dirty = false, - .parentid = bid, + .parentid = b->batCacheid, .farmid = BBPselectfarm(PERSISTENT, b->ttype, varheap), }; strconcat_len(b->tvheap->filename, sizeof(b->tvheap->filename), filename, ".theap", NULL); - ATOMIC_INIT(&b->tvheap->refs, 1); + } else { + b->tvheap = NULL; } return n; } +/* read a single line from the BBP.dir file (file pointer fp) and fill + * in the structure pointed to by bn and extra information through the + * other pointers; this function does not allocate any memory; return 0 + * on end of file, 1 on success, and -1 on failure */ +static int +BBPreadBBPline(FILE *fp, unsigned bbpversion, int *lineno, BAT *bn, + int *hashash, + char *batname, char *filename, char **options) +{ + char buf[4096]; + uint64_t batid; + uint16_t status; + unsigned int properties; + int nread, n; + char *s; + uint64_t count, capacity = 0, base = 0; + + if (fgets(buf, sizeof(buf), fp) == NULL) { + if (ferror(fp)) { + TRC_CRITICAL(GDK, "error reading BBP.dir on line %d\n", *lineno); + return -1; + } + return 0; /* end of file */ + } + (*lineno)++; + if ((s = strchr(buf, '\r')) != NULL) { + /* convert \r\n into just \n */ + if (s[1] != '\n') { + TRC_CRITICAL(GDK, "invalid format for BBP.dir on line %d", *lineno); + return -1; + } + *s++ = '\n'; + *s = 0; + } + + if (sscanf(buf, + "%" SCNu64 " %" SCNu16 " %128s %19s %u %" SCNu64 + " %" SCNu64 " %" SCNu64 + "%n", + &batid, &status, batname, filename, + &properties, + &count, &capacity, &base, + &nread) < 8) { + TRC_CRITICAL(GDK, "invalid format for BBP.dir on line %d", *lineno); + return -1; + } + + if (batid >= N_BBPINIT * BBPINIT) { + TRC_CRITICAL(GDK, "bat ID (%" PRIu64 ") too large to accomodate (max %d), on line %d.", batid, N_BBPINIT * BBPINIT - 1, *lineno); + return -1; + } + + /* convert both / and \ path separators to our own DIR_SEP */ +#if DIR_SEP != '/' + s = filename; + while ((s = strchr(s, '/')) != NULL) + *s++ = DIR_SEP; +#endif +#if DIR_SEP != '\\' + s = filename; + while ((s = strchr(s, '\\')) != NULL) + *s++ = DIR_SEP; +#endif + + bn->batCacheid = (bat) batid; + BATinit_idents(bn); + bn->batTransient = false; + bn->batCopiedtodisk = true; + switch ((properties & 0x06) >> 1) { + case 0: + bn->batRestricted = BAT_WRITE; + break; + case 1: + bn->batRestricted = BAT_READ; + break; + case 2: + bn->batRestricted = BAT_APPEND; + break; + default: + TRC_CRITICAL(GDK, "incorrect batRestricted value"); + return -1; + } + bn->batCount = (BUN) count; + bn->batInserted = bn->batCount; + /* set capacity to at least count */ + bn->batCapacity = (BUN) count <= BATTINY ? BATTINY : (BUN) count; + + if (base > (uint64_t) GDK_oid_max) { + TRC_CRITICAL(GDK, "head seqbase out of range (ID = %" PRIu64 ", seq = %" PRIu64 ") on line %d.", batid, base, *lineno); + return -1; + } + bn->hseqbase = (oid) base; + n = heapinit(bn, buf + nread, + hashash, + bbpversion, filename, *lineno); + if (n < 0) { + return -1; + } + nread += n; + n = vheapinit(bn, buf + nread, *hashash, filename, *lineno); + if (n < 0) { + return -1; + } + nread += n; + + if (buf[nread] != '\n' && buf[nread] != ' ') { + TRC_CRITICAL(GDK, "invalid format for BBP.dir on line %d", *lineno); + return -1; + } + *options = (buf[nread] == ' ') ? buf + nread + 1 : NULL; + return 1; +} + static gdk_return BBPreadEntries(FILE *fp, unsigned bbpversion, int lineno) { - bat bid = 0; - char buf[4096]; - /* read the BBP.dir and insert the BATs into the BBP */ - while (fgets(buf, sizeof(buf), fp) != NULL) { - BAT *bn; - uint64_t batid; - uint16_t status; + for (;;) { + BAT b; + Heap h; + Heap vh; + vh = h = (Heap) { + .free = 0, + }; + b = (BAT) { + .theap = &h, + .tvheap = &vh, + }; + char *options; char headname[129]; char filename[sizeof(BBP_physical(0))]; - unsigned int properties; - int nread, n; - char *s, *options = NULL; char logical[1024]; - uint64_t count, capacity, base = 0; int Thashash; - lineno++; - if ((s = strchr(buf, '\r')) != NULL) { - /* convert \r\n into just \n */ - if (s[1] != '\n') { - TRC_CRITICAL(GDK, "invalid format for BBP.dir on line %d", lineno); - return GDK_FAIL; - } - *s++ = '\n'; - *s = 0; - } - - if (sscanf(buf, - "%" SCNu64 " %" SCNu16 " %128s %19s %u %" SCNu64 - " %" SCNu64 " %" SCNu64 - "%n", - &batid, &status, headname, filename, - &properties, - &count, &capacity, &base, - &nread) < 8) { - TRC_CRITICAL(GDK, "invalid format for BBP.dir on line %d", lineno); - return GDK_FAIL; + switch (BBPreadBBPline(fp, bbpversion, &lineno, &b, + &Thashash, + headname, filename, &options)) { + case 0: + /* end of file */ + return GDK_SUCCEED; + case 1: + /* successfully read an entry */ + break; + default: + /* error */ + goto bailout; } - if (batid >= N_BBPINIT * BBPINIT) { - TRC_CRITICAL(GDK, "bat ID (%" PRIu64 ") too large to accomodate (max %d), on line %d.", batid, N_BBPINIT * BBPINIT - 1, lineno); - return GDK_FAIL; + if (b.batCacheid >= N_BBPINIT * BBPINIT) { + TRC_CRITICAL(GDK, "bat ID (%d) too large to accommodate (max %d), on line %d.", b.batCacheid, N_BBPINIT * BBPINIT - 1, lineno); + goto bailout; + } + + if (b.batCacheid >= (bat) ATOMIC_GET(&BBPsize)) { + if ((bat) ATOMIC_GET(&BBPsize) + 1 >= BBPlimit && + BBPextend(0, false, b.batCacheid + 1) != GDK_SUCCEED) + goto bailout; + ATOMIC_SET(&BBPsize, b.batCacheid + 1); } - - /* convert both / and \ path separators to our own DIR_SEP */ -#if DIR_SEP != '/' - s = filename; - while ((s = strchr(s, '/')) != NULL) - *s++ = DIR_SEP; -#endif -#if DIR_SEP != '\\' - s = filename; - while ((s = strchr(s, '\\')) != NULL) - *s++ = DIR_SEP; -#endif - - bid = (bat) batid; - if (batid >= (uint64_t) ATOMIC_GET(&BBPsize)) { - if ((bat) ATOMIC_GET(&BBPsize) + 1 >= BBPlimit && - BBPextend(0, false, bid + 1) != GDK_SUCCEED) - return GDK_FAIL; - ATOMIC_SET(&BBPsize, bid + 1); + if (BBP_desc(b.batCacheid) != NULL) { + TRC_CRITICAL(GDK, "duplicate entry in BBP.dir (ID = " + "%d) on line %d.", b.batCacheid, lineno); + goto bailout; } - if (BBP_desc(bid) != NULL) { - TRC_CRITICAL(GDK, "duplicate entry in BBP.dir (ID = " - "%" PRIu64 ") on line %d.", batid, lineno); - return GDK_FAIL; - } + + BAT *bn; + Heap *hn; if ((bn = GDKzalloc(sizeof(BAT))) == NULL || - (bn->theap = GDKzalloc(sizeof(Heap))) == NULL) { + (hn = GDKzalloc(sizeof(Heap))) == NULL) { GDKfree(bn); TRC_CRITICAL(GDK, "cannot allocate memory for BAT."); - return GDK_FAIL; _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org