void bptFileBulkIndexToOpenFile(void *itemArray, int itemSize, bits64 itemCount, bits32 blockSize, void (*fetchKey)(const void *va, char *keyBuf), bits32 keySize, void* (*fetchVal)(const void *va), bits32 valSize, FILE *f) /* Create a b+ tree index from a sorted array, writing output starting at current position * of an already open file. See bptFileCreate for explanation of parameters. */ { bits32 magic = bptSig; bits32 reserved = 0; writeOne(f, magic); writeOne(f, blockSize); writeOne(f, keySize); writeOne(f, valSize); writeOne(f, itemCount); writeOne(f, reserved); writeOne(f, reserved); bits64 indexOffset = ftell(f); /* Write non-leaf nodes. */ int levels = bptCountLevels(blockSize, itemCount); int i; for (i=levels-1; i > 0; --i) { bits32 endLevelOffset = writeIndexLevel(blockSize, itemArray, itemSize, itemCount, indexOffset, i, fetchKey, keySize, valSize, f); indexOffset = ftell(f); if (endLevelOffset != indexOffset) internalErr(); } /* Write leaf nodes */ writeLeafLevel(blockSize, itemArray, itemSize, itemCount, fetchKey, keySize, fetchVal, valSize, f); }
void writeIndex(struct chromInfo *chromList, int chromCount, char *fileName) /* Write index file - a b+ tree. */ { /* Open file and write out header. */ FILE *f = mustOpen(fileName, "w"); bits32 magic = chromSizeIndexSig; bits32 count = chromCount; bits16 bSize = blockSize; bits16 reserved16 = 0; bits32 reserved32 = 0; writeOne(f, magic); writeOne(f, chromCount); writeOne(f, bSize); writeOne(f, reserved16); writeOne(f, reserved32); bits32 indexOffset = ftell(f); /* Make array for all chromosomes. */ struct chromInfo *chrom, **chromArray; AllocArray(chromArray, chromCount); int i; for (i=0, chrom=chromList; i<chromCount; ++i, chrom=chrom->next) chromArray[i] = chrom; /* Figure out how many levels in B tree, and number of chroms between items at highest level. */ int levels = countLevels(blockSize, chromCount); verbose(1, "%d levels with blockSize %d covers %d items\n", levels, blockSize, chromCount); /* Write non-leaf nodes. */ for (i=levels-1; i > 0; --i) { bits32 endLevelOffset = writeIndexLevel(chromArray, chromCount, indexOffset, i, f); indexOffset = ftell(f); if (endLevelOffset != indexOffset) errAbort("internal err: mismatch endLevelOffset=%u vs indexOffset=%u", endLevelOffset, indexOffset); } /* Write leaf nodes */ writeLeafLevel(chromArray, chromCount, f); /* Clean up and go home. */ freez(&chromArray); carefulClose(&f); }
static void writeTreeToOpenFile(struct rTree *tree, int blockSize, int levelCount, FILE *f) /* Write out tree to a file that is open already - writing out index nodes from * highest to lowest level, and then leaf nodes. */ { /* Calculate sizes of each level. */ int i; int levelSizes[levelCount]; for (i=0; i<levelCount; ++i) levelSizes[i] = 0; calcLevelSizes(tree, levelSizes, 0, levelCount-1); /* Calc offsets of each level. */ bits64 levelOffsets[levelCount]; bits64 offset = ftell(f); bits64 iNodeSize = indexNodeSize(blockSize); bits64 lNodeSize = leafNodeSize(blockSize); for (i=0; i<levelCount; ++i) { levelOffsets[i] = offset; offset += levelSizes[i] * iNodeSize; verbose(2, "level %d: size %d, offset %llu\n", i, levelSizes[i], levelOffsets[i]); } verbose(2, "%d levels. Level sizes are", levelCount); for (i=0; i<levelCount; ++i) verbose(2, " %d", levelSizes[i]); verbose(2, "\n"); /* Write out index levels. */ int finalLevel = levelCount-3; for (i=0; i<=finalLevel; ++i) { bits64 childNodeSize = (i==finalLevel ? lNodeSize : iNodeSize); writeIndexLevel(blockSize, childNodeSize, tree, levelOffsets[i+1], i, f); if (ftell(f) != levelOffsets[i+1]) errAbort("Internal error: offset mismatch (%llu vs %llu) line %d of %s\n", (bits64)ftell(f), levelOffsets[i+1], __LINE__, __FILE__); } /* Write out leaf level. */ int leafLevel = levelCount - 2; writeLeaves(blockSize, leafNodeSize(blockSize), tree, leafLevel, f); }