/// <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); }); }
/// <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); }