Skip to content

Commit

Permalink
docs: improved comments and started example app
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveRuble committed Oct 3, 2021
1 parent f13d406 commit b5a2edd
Show file tree
Hide file tree
Showing 23 changed files with 488 additions and 85 deletions.
6 changes: 6 additions & 0 deletions Bloomn.sln
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bloomn.Tests", "tests\Bloom
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bloomn.Benchmarks", "tests\Bloomn.Benchmarks\Bloomn.Benchmarks.csproj", "{D00EC957-A24D-4061-907C-F7E9E24D489C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bloomn.Cli", "examples\Bloomn.Cli\Bloomn.Cli.csproj", "{89A7A037-CFCB-429D-A862-F12256E286C7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -24,5 +26,9 @@ Global
{D00EC957-A24D-4061-907C-F7E9E24D489C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D00EC957-A24D-4061-907C-F7E9E24D489C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D00EC957-A24D-4061-907C-F7E9E24D489C}.Release|Any CPU.Build.0 = Release|Any CPU
{89A7A037-CFCB-429D-A862-F12256E286C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{89A7A037-CFCB-429D-A862-F12256E286C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89A7A037-CFCB-429D-A862-F12256E286C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89A7A037-CFCB-429D-A862-F12256E286C7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
9 changes: 9 additions & 0 deletions examples/Bloomn.Cli/Bloomn.Cli.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
156 changes: 156 additions & 0 deletions examples/Bloomn.Cli/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;

namespace Bloomn.Cli
{
internal static class Constants
{
public const string Add = "add";
public const string Check = "check";
public const string Show = "show";
public const string Create = "create";
public const string StateFlag = "--state";
public const string StateShortFlag = "-s";
public const string StateEnv = "BLOOMN_STATE";
}

class Program
{
[DoesNotReturn]
public static void Help(string? command, string? error)
{
if (error != null)
{
Console.WriteLine(error);
Console.WriteLine();
}

Console.WriteLine($"For all commands, the path of the state/config file can be provided as {Constants.StateShortFlag}|{Constants.StateFlag} or as an environment variable {Constants.StateEnv}.");

switch (command)
{
case Constants.Add:
Console.WriteLine("Provide a newline delimited list of keys to add, or the command will read from stdin. ");
break;
case Constants.Check:
Console.WriteLine("Provide a newline delimited list of keys to check, or the command will read from stdin. The command will print `{key} : {0|1}` for each key provided.");
break;
case Constants.Show:
Console.WriteLine("Prints the configuration of the filter from the state file.");
break;
case Constants.Create:
Console.WriteLine("Creates a default, empty state file.");
break;
default:
Console.WriteLine(@"Commands:
add Add keys to filter
check Check if keys are present in filter
create Create a new filter by saving a default config
show Print off configuration of filter");
break;

}

if (error != null)
{
Environment.Exit(1);
}
else
{
Environment.Exit(0);
}
}

private static string ExtractFlagValue(int index, string flag, string[] args)
{
if (flag.Contains("="))
{
return flag.Split("=").Last();
}

if (flag.StartsWith("--"))
{
if (args.Length >= index + 2)
{
return args[index + 1];
}
Console.WriteLine($"Flag {flag} requires a parameter");
}

return flag.Substring(2);
}

static void Main(string[] args)
{
if (args.Length == 0)
{
Help(null, null);
}

var cmd = args[0];

var stateFilePath = Environment.GetEnvironmentVariable(Constants.StateEnv);

for (int i = 0; i < args.Length; i++)
{
var flag = args[i];
if (flag.StartsWith(Constants.StateShortFlag) || flag.StartsWith(Constants.StateFlag))
{
stateFilePath = ExtractFlagValue(i, flag, args);
}
}

var app = new App()
{
StateFilePath = stateFilePath,
};

switch (cmd)
{
case Constants.Add:
app.Add();
break;
case Constants.Check:
app.Check();
break;
case Constants.Show:
app.Show();
break;
case Constants.Create:
app.Create();
break;
default:
Help(cmd, null);
break;
}

}
}

public class App
{
public string? StateFilePath { get; set; }

public void Add()
{
throw new NotImplementedException();
}

public void Check()
{
throw new NotImplementedException();
}

public void Show()
{
throw new NotImplementedException();
}

public void Create()
{
throw new NotImplementedException();
}
}
}
32 changes: 32 additions & 0 deletions src/Bloomn/Behaviors/MaxCapacityBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Bloomn.Behaviors
{
public enum MaxCapacityBehavior
{
/// <summary>
/// The bloom filter will throw an exception when it hits capacity.
/// </summary>
Throw,

/// <summary>
/// The bloom filter will scale up when it reaches capacity, using the algorithm from "Scalable Bloom Filters".
/// Enabling scaling allows you to avoid over-allocating storage when you don't know how many items you'll
/// need to add to the filter. However, if you do know how many items you need to add you will get better performance
/// and storage efficiency by specifying the capacity initially.
/// <para>
/// https://doi.org/10.1016/j.ipl.2006.10.007
/// </para>
/// <para>
/// https://haslab.uminho.pt/cbm/files/dbloom.pdf
/// </para>
/// <para>
/// Almeida, P. S. et al. “Scalable Bloom Filters.” Inf. Process. Lett. 101 (2007): 255-261.
/// </para>
/// </summary>
Scale,

/// <summary>
/// The bloom filter will continue to add items even if it can no longer fulfil the requested error rate.
/// </summary>
Ignore
}
}
23 changes: 23 additions & 0 deletions src/Bloomn/Behaviors/StateValidationBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace Bloomn.Behaviors
{
public enum StateValidationBehavior
{
/// <summary>
/// Default behavior: throws if you attempt to import state which
/// has different parameters than the those used to configure the builder.
/// </summary>
ThrowIfInconsistent,

/// <summary>
/// If an imported state is inconsistent with the builder configuration,
/// the builder configuration is ignored.
/// </summary>
PreferStateConfiguration,

/// <summary>
/// If the imported state is inconsistent with the builder configuration,
/// the imported state is ignored.
/// </summary>
DiscardInconsistentState,
}
}
25 changes: 24 additions & 1 deletion src/Bloomn/BloomFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@ namespace Bloomn
{
public static class BloomFilter
{
public static IBloomFilterBuilder<TKey> Builder<TKey>() => new BloomFilterBuilder<TKey>(new BloomFilterOptions<TKey>());
/// <summary>
/// Create a new builder with default options.
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <returns></returns>
public static IBloomFilterBuilder<TKey> Builder<TKey>() => new BloomFilterBuilder<TKey>();

/// <summary>
/// Create a new builder with the provided options.
/// </summary>
/// <param name="options"></param>
/// <param name="cloneOptions">
/// Optional; if true, the provided options will be cloned and any changes made by
/// the builder will only be applied to the cloned version. Defaults to true.
/// </param>
public static IBloomFilterBuilder<TKey> Builder<TKey>(BloomFilterOptions<TKey> options, bool cloneOptions = true) => new BloomFilterBuilder<TKey>(new BloomFilterOptions<TKey>());

/// <summary>
/// Create a new builder directly from state.
/// </summary>
/// <param name="state"></param>
/// <typeparam name="TKey"></typeparam>
/// <returns></returns>
public static IBloomFilterBuilder<TKey> Builder<TKey>(BloomFilterState state) => new BloomFilterBuilder<TKey>(state);
}
}
Loading

0 comments on commit b5a2edd

Please sign in to comment.