NOTE: Arguments here are named and structured identically to those in the PostgreSQL implementation, which can be found here . @param log2m log-base-2 of th
(final int log2m, final int regwidth, final int expthresh, final boolean sparseon, final HLLType type)
| 179 | * start at. This cannot be <code>null</code>. |
| 180 | */ |
| 181 | public HLL(final int log2m, final int regwidth, final int expthresh, final boolean sparseon, final HLLType type) { |
| 182 | this.log2m = log2m; |
| 183 | if((log2m < MINIMUM_LOG2M_PARAM) || (log2m > MAXIMUM_LOG2M_PARAM)) { |
| 184 | throw new IllegalArgumentException("'log2m' must be at least " + MINIMUM_LOG2M_PARAM + " and at most " + MAXIMUM_LOG2M_PARAM + " (was: " + log2m + ")"); |
| 185 | } |
| 186 | |
| 187 | this.regwidth = regwidth; |
| 188 | if((regwidth < MINIMUM_REGWIDTH_PARAM) || (regwidth > MAXIMUM_REGWIDTH_PARAM)) { |
| 189 | throw new IllegalArgumentException("'regwidth' must be at least " + MINIMUM_REGWIDTH_PARAM + " and at most " + MAXIMUM_REGWIDTH_PARAM + " (was: " + regwidth + ")"); |
| 190 | } |
| 191 | |
| 192 | this.m = (1 << log2m); |
| 193 | this.mBitsMask = m - 1; |
| 194 | this.valueMask = (1 << regwidth) - 1; |
| 195 | this.pwMaxMask = HLLUtil.pwMaxMask(regwidth); |
| 196 | this.alphaMSquared = HLLUtil.alphaMSquared(m); |
| 197 | this.smallEstimatorCutoff = HLLUtil.smallEstimatorCutoff(m); |
| 198 | this.largeEstimatorCutoff = HLLUtil.largeEstimatorCutoff(log2m, regwidth); |
| 199 | |
| 200 | if(expthresh == -1) { |
| 201 | this.explicitAuto = true; |
| 202 | this.explicitOff = false; |
| 203 | |
| 204 | // NOTE: This math matches the size calculation in the PostgreSQL impl. |
| 205 | final long fullRepresentationSize = (this.regwidth * (long)this.m + 7/*round up to next whole byte*/)/Byte.SIZE; |
| 206 | final int numLongs = (int)(fullRepresentationSize / 8/*integer division to round down*/); |
| 207 | |
| 208 | if(numLongs > MAXIMUM_EXPLICIT_THRESHOLD) { |
| 209 | this.explicitThreshold = MAXIMUM_EXPLICIT_THRESHOLD; |
| 210 | } else { |
| 211 | this.explicitThreshold = numLongs; |
| 212 | } |
| 213 | } else if(expthresh == 0) { |
| 214 | this.explicitAuto = false; |
| 215 | this.explicitOff = true; |
| 216 | this.explicitThreshold = 0; |
| 217 | } else if((expthresh > 0) && (expthresh <= MAXIMUM_EXPTHRESH_PARAM)){ |
| 218 | this.explicitAuto = false; |
| 219 | this.explicitOff = false; |
| 220 | this.explicitThreshold = (1 << (expthresh - 1)); |
| 221 | } else { |
| 222 | throw new IllegalArgumentException("'expthresh' must be at least " + MINIMUM_EXPTHRESH_PARAM + " and at most " + MAXIMUM_EXPTHRESH_PARAM + " (was: " + expthresh + ")"); |
| 223 | } |
| 224 | |
| 225 | this.shortWordLength = (regwidth + log2m); |
| 226 | this.sparseOff = !sparseon; |
| 227 | if(this.sparseOff) { |
| 228 | this.sparseThreshold = 0; |
| 229 | } else { |
| 230 | // TODO improve this cutoff to include the cost overhead of Java |
| 231 | // members/objects |
| 232 | final int largestPow2LessThanCutoff = |
| 233 | (int)NumberUtil.log2((this.m * this.regwidth) / this.shortWordLength); |
| 234 | this.sparseThreshold = (1 << largestPow2LessThanCutoff); |
| 235 | } |
| 236 | |
| 237 | initializeStorage(type); |
| 238 | } |
nothing calls this directly
no test coverage detected