Ejemplo n.º 1
0
        /// <summary>
        /// Convert a <see cref="IInvertibleBloomFilterData{TId, THash, TCount}"/> to a concrete <see cref="InvertibleBloomFilterData{TId, THash, TCount}"/>.
        /// </summary>
        /// <typeparam name="TId">The identifier type</typeparam>
        /// <typeparam name="THash">The entity hash type</typeparam>
        /// <typeparam name="TCount">The occurence count type</typeparam>
        /// <param name="filterData">The IBF data</param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        internal static InvertibleBloomFilterData <TId, THash, TCount> ConvertToBloomFilterData <TId, THash, TCount>(
            this IInvertibleBloomFilterData <TId, THash, TCount> filterData,
            ICountingBloomFilterConfiguration <TId, THash, TCount> configuration)
            where TId : struct
            where TCount : struct
            where THash : struct
        {
            if (filterData == null)
            {
                return(null);
            }
            var result = filterData as InvertibleBloomFilterData <TId, THash, TCount>;

            if (result != null)
            {
                result.SyncCompressionProviders(configuration);
                return(result);
            }
            var res = new InvertibleBloomFilterData <TId, THash, TCount>
            {
                HashFunctionCount = filterData.HashFunctionCount,
                BlockSize         = filterData.BlockSize,
                HashSums          = filterData.HashSumProvider.ToArray(),
                Counts            = filterData.Counts,
                IdSums            = filterData.IdSumProvider.ToArray(),
                IsReverse         = filterData.IsReverse,
                SubFilter         = filterData.SubFilter,
                Capacity          = filterData.Capacity,
                ItemCount         = filterData.ItemCount,
                ErrorRate         = filterData.ErrorRate
            };

            res.SyncCompressionProviders(configuration);
            return(res);
        }
        /// <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);
        }