/// <summary> /// Lower the strata on the estimator. /// </summary> /// <typeparam name="TId"></typeparam> /// <typeparam name="TCount"></typeparam> /// <param name="data"></param> /// <param name="newStrata"></param> internal static void LowerStrata <TId, TCount>(this StrataEstimatorData <TId, TCount> data, byte newStrata) where TId : struct where TCount : struct { if (data == null || newStrata >= data.StrataCount) { return; } var newFilters = new List <IInvertibleBloomFilterData <TId, int, TCount> >(data.BloomFilters); var indexes = new List <byte>(data.BloomFilterStrataIndexes ?? new byte[0]); for (var i = newStrata; i < data.StrataCount; i++) { var filter = data.GetFilterForStrata(i); if (filter != null) { indexes.Remove(i); newFilters.Remove(filter); } } data.BloomFilters = newFilters.Cast <InvertibleBloomFilterData <TId, int, TCount> >().ToArray(); if (data.BloomFilterStrataIndexes != null) { data.BloomFilterStrataIndexes = indexes.Count == 0 ? null : indexes.ToArray(); } data.StrataCount = newStrata; }
/// <summary> /// Intersect the given strata estimators. /// </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="data">Estimator data</param> /// <param name="otherEstimatorData">The other estimate</param> /// <param name="configuration">The Bloom filter configuration</param> /// <param name="maxStrata">The maximum strata</param> /// <param name="destructive">When <c>true</c> the <paramref name="data"/> will be altered and no longer usable, else <c>false</c></param> /// <returns></returns> internal static StrataEstimatorData <int, TCount> Intersect <TEntity, TId, TCount>(this IStrataEstimatorData <int, TCount> data, IStrataEstimatorData <int, TCount> otherEstimatorData, IInvertibleBloomFilterConfiguration <TEntity, TId, int, TCount> configuration) where TId : struct where TCount : struct { if (data == null && otherEstimatorData == null) { return(null); } if (data == null) { return(new StrataEstimatorData <int, TCount> { BlockSize = otherEstimatorData.BlockSize, DecodeCountFactor = otherEstimatorData.DecodeCountFactor, HashFunctionCount = otherEstimatorData.HashFunctionCount, StrataCount = otherEstimatorData.StrataCount }); } var strataConfig = configuration.ConvertToEstimatorConfiguration(); var fold = configuration.FoldingStrategy?.GetFoldFactors(data.BlockSize, otherEstimatorData?.BlockSize ?? data.BlockSize); var res = new StrataEstimatorData <int, TCount> { BlockSize = data.BlockSize / (fold?.Item1 ?? 1L), BloomFilterStrataIndexes = data.BloomFilterStrataIndexes, BloomFilters = data.BloomFilters?.Select(b => b.ConvertToBloomFilterData(strataConfig)).ToArray(), DecodeCountFactor = data.DecodeCountFactor, HashFunctionCount = data.HashFunctionCount, StrataCount = data.StrataCount }; var minStrata = Math.Min(data.StrataCount, otherEstimatorData.StrataCount); for (var i = minStrata - 1; i >= 0; i--) { var ibf = data.GetFilterForStrata(i); var estimatorIbf = i >= otherEstimatorData.StrataCount ? null : otherEstimatorData.GetFilterForStrata(i); if (ibf == null && estimatorIbf == null) { continue; } res.BloomFilters[i] = ibf.Intersect(strataConfig, estimatorIbf); } return(res); }
/// <summary> /// Fold the strata estimator data. /// </summary> /// <typeparam name="TEntity"></typeparam> /// <typeparam name="TId"></typeparam> /// <typeparam name="TCount"></typeparam> /// <param name="estimatorData"></param> /// <param name="configuration"></param> /// <param name="factor"></param> /// <returns></returns> internal static StrataEstimatorData <int, TCount> Fold <TEntity, TId, TCount>( this IStrataEstimatorData <int, TCount> estimatorData, IInvertibleBloomFilterConfiguration <TEntity, TId, int, TCount> configuration, uint factor) where TCount : struct where TId : struct { if (estimatorData?.BloomFilters == null) { return(null); } var filterConfig = configuration.ConvertToEstimatorConfiguration(); var res = new StrataEstimatorData <int, TCount> { BloomFilters = estimatorData.BloomFilters == null ? null : new InvertibleBloomFilterData <int, int, TCount> [estimatorData.BloomFilters.Length], BloomFilterStrataIndexes = estimatorData.BloomFilterStrataIndexes?.ToArray(), BlockSize = estimatorData.BlockSize / factor, DecodeCountFactor = estimatorData.DecodeCountFactor, StrataCount = estimatorData.StrataCount }; for (var j = 0L; j < res.BloomFilters.Length; j++) { estimatorData .BloomFilters[j] .SyncCompressionProviders(filterConfig); res.BloomFilters[j] = estimatorData .BloomFilters[j] .Fold(filterConfig, factor) .ConvertToBloomFilterData(filterConfig); } return(res); }