Ejemplo n.º 1
0
 /// <summary>
 /// Add an item from the given position.
 /// </summary>
 /// <typeparam name="TEntity">The entity type</typeparam>
 /// <typeparam name="TId">The type of the entity identifier</typeparam>
 /// <typeparam name="TCount">The type of the Bloom filter occurence count</typeparam>
 /// <param name="filter"></param>
 /// <param name="configuration"></param>
 /// <param name="idValue"></param>
 /// <param name="hashValue"></param>
 /// <param name="position"></param>
 internal static void Add <TEntity, TId, TCount>(
     this IInvertibleBloomFilterData <TId, int, TCount> filter,
     IInvertibleBloomFilterConfiguration <TEntity, TId, int, TCount> configuration,
     TId idValue,
     int hashValue,
     long position)
     where TCount : struct
     where TId : struct
 {
     if (filter == null)
     {
         return;
     }
     filter.ExecuteExclusively(position, () =>
     {
         filter.Counts[position]          = configuration.CountConfiguration.Increase(filter.Counts[position]);
         filter.HashSumProvider[position] = configuration.HashAdd(filter.HashSumProvider[position], hashValue);
         filter.IdSumProvider[position]   = configuration.IdAdd(filter.IdSumProvider[position], idValue);
     });
 }
Ejemplo n.º 2
0
        ///  <summary>
        ///  Add two filters.
        ///  </summary>
        ///  <typeparam name="TEntity">The entity type</typeparam>
        ///  <typeparam name="TId">The type of the entity identifier</typeparam>
        ///  <typeparam name="TCount">The type of the Bloom filter occurence count</typeparam>
        /// <typeparam name="THash"></typeparam>
        /// <param name="filterData"></param>
        ///  <param name="configuration"></param>
        ///  <param name="otherFilterData"></param>
        ///  <param name="inPlace">When <c>true</c> the <paramref name="otherFilterData"/> will be added to the <paramref name="filterData"/> instance, otheerwise a new instance of the filter data will be returned.</param>
        ///  <returns>The filter data or <c>null</c> when the addition failed.</returns>
        /// <remarks></remarks>
        public static IInvertibleBloomFilterData <TId, THash, TCount> Add <TEntity, TId, THash, TCount>(
            this IInvertibleBloomFilterData <TId, THash, TCount> filterData,
            IInvertibleBloomFilterConfiguration <TEntity, TId, THash, TCount> configuration,
            IInvertibleBloomFilterData <TId, THash, TCount> otherFilterData,
            bool inPlace = true)
            where TCount : struct
            where TId : struct
            where THash : struct
        {
            if (filterData == null && otherFilterData == null)
            {
                return(null);
            }
            if (filterData == null)
            {
                filterData = otherFilterData.CreateDummy(configuration);
                inPlace    = true;
            }
            else
            {
                filterData.SyncCompressionProviders(configuration);
            }
            if (otherFilterData == null)
            {
                otherFilterData = filterData.CreateDummy(configuration);
            }
            else
            {
                otherFilterData.SyncCompressionProviders(configuration);
            }
            if (!filterData.IsCompatibleWith(otherFilterData, configuration))
            {
                return(null);
            }
            var foldFactors = configuration.FoldingStrategy?.GetFoldFactors(filterData.BlockSize, otherFilterData.BlockSize);
            var res         = inPlace && foldFactors?.Item1 <= 1 ?
                              filterData :
                              (foldFactors == null || foldFactors.Item1 <= 1 ?
                               filterData.CreateDummy(configuration) :
                               configuration.DataFactory.Create(
                                   configuration,
                                   filterData.Capacity / foldFactors.Item1,
                                   filterData.BlockSize / foldFactors.Item1,
                                   filterData.HashFunctionCount));

            foldFactors   = foldFactors ?? new Tuple <long, long>(1, 1);
            res.IsReverse = filterData.IsReverse;
            Parallel.ForEach(
                Partitioner.Create(0L, res.BlockSize),
                (range, state) =>
            {
                for (var i = range.Item1; i < range.Item2; i++)
                {
                    res.Counts[i] = configuration.CountConfiguration.Add(
                        filterData.Counts.GetFolded(i, foldFactors.Item1, configuration.CountConfiguration.Add),
                        otherFilterData.Counts.GetFolded(i, foldFactors.Item2, configuration.CountConfiguration.Add));
                    res.HashSumProvider[i] = configuration.HashAdd(
                        filterData.HashSumProvider.GetFolded(i, filterData.BlockSize, foldFactors.Item1, configuration.HashAdd),
                        otherFilterData.HashSumProvider.GetFolded(i, otherFilterData.BlockSize, foldFactors.Item2, configuration.HashAdd));
                    res.IdSumProvider[i] = configuration.IdAdd(
                        filterData.IdSumProvider.GetFolded(i, filterData.BlockSize, foldFactors.Item1, configuration.IdAdd),
                        otherFilterData.IdSumProvider.GetFolded(i, otherFilterData.BlockSize, foldFactors.Item2, configuration.IdAdd));
                }
            });
            res.SubFilter = filterData
                            .SubFilter
                            .Add(configuration.SubFilterConfiguration, otherFilterData.SubFilter, inPlace)
                            .ConvertToBloomFilterData(configuration);
            res.ItemCount = filterData.ItemCount + otherFilterData.ItemCount;
            return(res);
        }