/// <summary> /// Fold the strata estimator data. /// </summary> /// <typeparam name="TEntity">The entity type</typeparam> /// <typeparam name="TId">The identifier type</typeparam> /// <typeparam name="TCount">The count type</typeparam> /// <param name="estimatorData"></param> /// <param name="configuration"></param> /// <param name="factor">The factor to fold by</param> /// <returns>The <paramref name="estimatorData"/> folded by <paramref name="factor"/>.</returns> internal static HybridEstimatorFullData <int, TCount> Fold <TEntity, TId, TCount>( this IHybridEstimatorFullData <int, TCount> estimatorData, IInvertibleBloomFilterConfiguration <TEntity, TId, int, TCount> configuration, uint factor) where TCount : struct where TId : struct { if (estimatorData == null) { return(null); } var minWiseFold = Math.Max( 1L, configuration .FoldingStrategy? .GetAllFoldFactors(estimatorData.BitMinwiseEstimator?.Capacity ?? 1L) .OrderBy(f => f) .FirstOrDefault(f => f > factor) ?? 1L); return(new HybridEstimatorFullData <int, TCount> { ItemCount = estimatorData.ItemCount, BitMinwiseEstimator = estimatorData.BitMinwiseEstimator?.Fold((uint)minWiseFold), StrataEstimator = estimatorData.StrataEstimator?.Fold(configuration.ConvertToEstimatorConfiguration(), factor) }); }
/// <summary> /// Intersect with the estimator. /// </summary> /// <param name="estimator"></param> public void Intersect(IHybridEstimatorFullData <int, TCount> estimator) { IHybridEstimator <TEntity, int, TCount> self = this; Rehydrate(self .FullExtract() .Intersect(_configuration, estimator)); }
/// <summary> /// Rehydrate the hybrid estimator from full data. /// </summary> /// <param name="data">The data to restore</param> public void Rehydrate(IHybridEstimatorFullData <int, TCount> data) { if (data == null) { return; } _minwiseEstimator?.Rehydrate(data.BitMinwiseEstimator); _strataEstimator.Rehydrate(data.StrataEstimator); _minwiseReplacementCount = Math.Max(0, data.ItemCount - (_strataEstimator.ItemCount + (_minwiseEstimator?.ItemCount ?? 0L))); }
/// <summary> /// Intersect two hybrid estimators /// </summary> /// <typeparam name="TEntity"></typeparam> /// <typeparam name="TId"></typeparam> /// <typeparam name="TCount"></typeparam> /// <param name="estimatorData"></param> /// <param name="configuration"></param> /// <returns></returns> internal static IHybridEstimatorFullData <int, TCount> Intersect <TEntity, TId, TCount>( this IHybridEstimatorFullData <int, TCount> estimatorData, IInvertibleBloomFilterConfiguration <TEntity, TId, int, TCount> configuration, IHybridEstimatorFullData <int, TCount> otherEstimatorData) where TId : struct where TCount : struct { if (estimatorData == null && otherEstimatorData == null) { return(null); } var res = new HybridEstimatorFullData <int, TCount>(); res.BitMinwiseEstimator = estimatorData?.BitMinwiseEstimator.Intersect(otherEstimatorData?.BitMinwiseEstimator, configuration.FoldingStrategy); res.StrataEstimator = estimatorData?.StrataEstimator.Intersect(otherEstimatorData?.StrataEstimator, configuration); res.ItemCount = (res.BitMinwiseEstimator?.ItemCount ?? 0L) + (res.StrataEstimator?.ItemCount ?? 0L); return(res); }
/// <summary> /// Compress the hybrid estimator. /// </summary> /// <typeparam name="TEntity"></typeparam> /// <typeparam name="TId"></typeparam> /// <typeparam name="TCount"></typeparam> /// <param name="estimatorData"></param> /// <param name="configuration"></param> /// <returns></returns> internal static HybridEstimatorFullData <int, TCount> Compress <TEntity, TId, TCount>( this IHybridEstimatorFullData <int, TCount> estimatorData, IInvertibleBloomFilterConfiguration <TEntity, TId, int, TCount> configuration) where TCount : struct where TId : struct { if (configuration?.FoldingStrategy == null || estimatorData == null) { return(null); } var fold = configuration.FoldingStrategy.FindCompressionFactor( configuration, estimatorData.StrataEstimator.BlockSize, estimatorData.StrataEstimator.BlockSize, estimatorData.ItemCount); var res = fold.HasValue ? estimatorData.Fold(configuration, fold.Value) : null; return(res); }