/// <summary>
        /// Create new Bloom filter data based upon the size and the hash function count.
        /// </summary>
        /// <typeparam name="TId">Type of the identifier</typeparam>
        /// <typeparam name="TCount">Type of the counter</typeparam>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="capacity"></param>
        /// <param name="m">Size per hash function</param>
        /// <param name="k">The number of hash functions.</param>
        /// <returns>The Bloom filter data</returns>
        public InvertibleBloomFilterData <TId, THash, TCount> Create <TEntity, TId, THash, TCount>(
            IInvertibleBloomFilterConfiguration <TEntity, TId, THash, TCount> configuration,
            long capacity,
            long m,
            uint k)
            where TId : struct
            where TCount : struct
            where THash : struct
        {
            if (m < 1) // from overflow in bestM calculation
            {
                throw new ArgumentOutOfRangeException(
                          nameof(m),
                          "The provided capacity and errorRate values would result in an array of length > long.MaxValue. Please reduce either the capacity or the error rate.");
            }
            var res = new InvertibleBloomFilterData <TId, THash, TCount>
            {
                HashFunctionCount = k,
                BlockSize         = m,
                Counts            = new TCount[m],
                Capacity          = capacity,
                ErrorRate         = configuration.ActualErrorRate(m, capacity, k)
            };

            res.SyncCompressionProviders(configuration);
            return(res);
        }