if (binMaxEntries <= 0) {
binMaxEntries = nodeMaxEntries;
}
final Environment env = openCalcEnvironment(true);
boolean success = false;
try {
envOverhead = env.getStats(null).getCacheTotalBytes();
final int density = orderedInsertion ?
ORDERED_DENSITY :
DEFAULT_DENSITY;
final int nodeAvg = (nodeMaxEntries * density) / 100;
final int binAvg = (binMaxEntries * density) / 100;
final long nBinNodes = (records + binAvg - 1) / binAvg;
calcTreeSizes(env, nodeAvg, binAvg);
/* Bottom level. */
numLevel[0] = nBinNodes;
minLevel[0] = nBinNodes * minBinSize;
maxLevel[0] = nBinNodes * maxBinSize;
btreeLevels = 1;
/* Upper levels. */
for (long nodes = (long) (nBinNodes / nodeAvg);; nodes /= nodeAvg) {
if (btreeLevels >= MAX_LEVELS) {
throw new IllegalArgumentException
("Maximum levels (" + MAX_LEVELS + ") exceeded.");
}
if (nodes == 0) {
nodes = 1; // root
}
numLevel[btreeLevels] = nodes;
minLevel[btreeLevels] = nodes * minInSize;
maxLevel[btreeLevels] = nodes * maxInSize;
btreeLevels += 1;
if (nodes == 1) {
break;
}
}
/* Totals without data. */
minBtreeSize = 0;
maxBtreeSize = 0;
for (int level = 0; level < btreeLevels; level += 1) {
minBtreeSize += minLevel[level];
maxBtreeSize += maxLevel[level];
}
/* Totals with data. */
minBtreeSizeWithData = nBinNodes * minBinSizeWithData;
maxBtreeSizeWithData = nBinNodes * maxBinSizeWithData;
for (int level = 1; level < btreeLevels; level += 1) {
minBtreeSizeWithData += minLevel[level];
maxBtreeSizeWithData += maxLevel[level];
}
success = true;
} finally {
/*
* Do not propgate exception thrown by Environment.close if another
* exception is currently in flight.
*/
try {
env.close();
} catch (RuntimeException e) {
if (success) {
throw e;
}
}