/// <summary>
        /// Compress the hybrid estimator.
        /// </summary>
        /// <param name="inPlace"></param>
        /// <returns></returns>
        public IHybridEstimator <TEntity, int, TCount> Compress(bool inPlace)
        {
            IHybridEstimator <TEntity, int, TCount> self = this;
            var res = FullExtract().Compress(_configuration);

            if (inPlace)
            {
                self.Rehydrate(res);
                return(this);
            }
            IHybridEstimator <TEntity, int, TCount> estimator = new HybridEstimator <TEntity, TId, TCount>(
                res.StrataEstimator.BlockSize,
                res.StrataEstimator.StrataCount,
                _configuration);

            if (res.BitMinwiseEstimator != null)
            {
                estimator.Initialize(
                    res.BitMinwiseEstimator.Capacity + res.ItemCount,
                    res.BitMinwiseEstimator.BitSize,
                    res.BitMinwiseEstimator.HashCount);
            }
            estimator.Rehydrate(res);
            return(estimator);
        }
        /// <summary>
        /// Create an estimator that matches the given <paramref name="data"/> estimator.
        /// </summary>
        /// <typeparam name="TEntity">The type of the entity</typeparam>
        /// <typeparam name="TId">The type of the identifier</typeparam>
        /// <typeparam name="TCount">The type of the occurence count</typeparam>
        /// <param name="data">The estimator data to match</param>
        /// <param name="configuration">The Bloom filter configuration</param>
        /// <param name="setSize">The (estimated) size of the set to add to the estimator.</param>
        /// <returns>An estimator</returns>
        public IHybridEstimator <TEntity, int, TCount> CreateMatchingEstimator <TEntity, TId, TCount>(
            IHybridEstimatorData <int, TCount> data,
            IInvertibleBloomFilterConfiguration <TEntity, TId, int, TCount> configuration,
            long setSize)
            where TCount : struct
            where TId : struct
        {
            var estimator = new HybridEstimator <TEntity, TId, TCount>(
                data.StrataEstimator.BlockSize,
                data.StrataEstimator.StrataCount,
                configuration,
                fixedBlockSize: true)
            {
                DecodeCountFactor = data.StrataEstimator.DecodeCountFactor
            };

            if (data.BitMinwiseEstimator != null)
            {
                estimator.Initialize(setSize, data.BitMinwiseEstimator.BitSize, data.BitMinwiseEstimator.HashCount);
            }
            return(estimator);
        }
        /// <summary>
        /// Create a hybrid estimator
        /// </summary>
        /// <typeparam name="TEntity">The entity type</typeparam>
        /// <typeparam name="TId">The type of the entity identifier</typeparam>
        /// <typeparam name="TCount">The type of occurence count.</typeparam>
        /// <param name="configuration">Bloom filter configuration</param>
        /// <param name="setSize">Number of elements in the set that is added.</param>
        /// <param name="failedDecodeCount">Number of times decoding has failed based upon the provided estimator.</param>
        /// <returns></returns>
        public HybridEstimator <TEntity, TId, TCount> Create <TEntity, TId, TCount>(
            IInvertibleBloomFilterConfiguration <TEntity, TId, int, TCount> configuration,
            long setSize,
            byte failedDecodeCount = 0)
            where TCount : struct
            where TId : struct
        {
            var minwiseHashCount = GetRecommendedMinwiseHashCount(configuration, setSize, failedDecodeCount);
            var strata           = GetRecommendedStrata(configuration, setSize, failedDecodeCount);
            var capacity         = GetRecommendedBlockSize(configuration, setSize, failedDecodeCount);
            var bitSize          = GetRecommendedBitSize(configuration, setSize, failedDecodeCount);
            var result           = new HybridEstimator <TEntity, TId, TCount>(
                capacity,
                strata,
                configuration);

            result.Initialize(setSize, bitSize, minwiseHashCount);
            if (failedDecodeCount > 1)
            {
                result.DecodeCountFactor = Math.Pow(2, failedDecodeCount);
            }
            return(result);
        }