public ImplicitWordHashMap(final LongArray numNgramsForEachWord, final long[] wordRanges, final int ngramOrder, final int maxNgramOrder,
final long numNgramsForPreviousOrder, final int totalNumWords, final HashNgramMap<?> ngramMap, final boolean fitsInInt, final boolean storeWords) {
this.ngramOrder = ngramOrder;
this.ngramMap = ngramMap;
assert ngramOrder >= 1;
this.maxNgramOrder = maxNgramOrder;
this.totalNumWords = totalNumWords;
this.numWords = (int) numNgramsForEachWord.size();
this.fitsInInt = fitsInInt;
this.wordRanges = storeWords ? null : wordRanges;
final long totalNumNgrams = setWordRanges(numNgramsForEachWord, numWords);
numSuffixBits = CustomWidthArray.numBitsNeeded(numNgramsForPreviousOrder + 1);
final int numBitsHere = numSuffixBits + (storeWords ? CustomWidthArray.numBitsNeeded(totalNumWords) : 0);
keys = new CustomWidthArray(totalNumNgrams, numBitsHere, numBitsHere + ngramMap.getValues().numValueBits(ngramOrder));
keys.fill(EMPTY_KEY, totalNumNgrams);
numFilled = 0;
}