XXHash

Port of Rust's twox-hash crate.
git clone https://git.philomathiclife.com/repos/XXHash
Log | Files | Refs | README

commit 594db0523f89dc0a91f68b82d9a1fd88807434af
Author: Zack Newman <zack@philomathiclife.com>
Date:   Fri, 17 Mar 2023 15:17:06 -0600

initial

Diffstat:
A.editorconfig | 1114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A.gitignore | 2++
AAssemblyInfo.cs | 8++++++++
AHasher.cs | 393+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALICENSE-APACHE | 177+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALICENSE-MIT | 20++++++++++++++++++++
ALib.cs | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AREADME.md | 3+++
AXXHash.csproj | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 1877 insertions(+), 0 deletions(-)

diff --git a/.editorconfig b/.editorconfig @@ -0,0 +1,1113 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +# Don't use tabs for indentation. +[*] +indent_style = space +charset = utf-8 + +# XML project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] +indent_size = 2 + +# XML config files +[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_size = 2 + +# JSON files +[*.json] +indent_size = 2 + +# Powershell files +[*.ps1] +indent_size = 2 + +# Shell script files +[*.sh] +end_of_line = lf +indent_size = 2 + +# Code files +[*.{cs,csx,vb,vbx}] +# Indentation and spacing +indent_size = 4 +tab_width = 4 + +# New line preferences +end_of_line = lf +insert_final_newline = false +dotnet_style_allow_multiple_blank_lines_experimental = false:error +dotnet_style_allow_statement_immediately_after_block_experimental = true:error + +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = false +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false:error +dotnet_style_qualification_for_field = false:error +dotnet_style_qualification_for_method = false:error +dotnet_style_qualification_for_property = false:error + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:error +dotnet_style_predefined_type_for_member_access = true:error + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:error +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:error +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:error +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:error + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = omit_if_default:error + +# Expression-level preferences +dotnet_style_coalesce_expression = true:error +dotnet_style_collection_initializer = true:error +dotnet_style_explicit_tuple_names = true:error +dotnet_style_null_propagation = true:error +dotnet_style_object_initializer = true:error +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true:error +dotnet_style_prefer_compound_assignment = true:error +dotnet_style_prefer_conditional_expression_over_assignment = true:error +dotnet_style_prefer_conditional_expression_over_return = true:error +dotnet_style_prefer_inferred_anonymous_type_member_names = true:error +dotnet_style_prefer_inferred_tuple_names = true:error +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:error +dotnet_style_prefer_simplified_boolean_expressions = true:error +dotnet_style_prefer_simplified_interpolation = true:suggestion + +# Field preferences +dotnet_style_readonly_field = true:error + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:error + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = error + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = true:error +csharp_style_var_for_built_in_types = true:error +csharp_style_var_when_type_is_apparent = true:error + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:error +csharp_style_expression_bodied_constructors = true:error +csharp_style_expression_bodied_indexers = true:error +csharp_style_expression_bodied_lambdas = true:error +csharp_style_expression_bodied_local_functions = true:error +csharp_style_expression_bodied_methods = true:error +csharp_style_expression_bodied_operators = true:error +csharp_style_expression_bodied_properties = true:error + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:error +csharp_style_pattern_matching_over_is_with_cast_check = true:error +csharp_style_prefer_not_pattern = true:error +csharp_style_prefer_pattern_matching = true:error +csharp_style_prefer_switch_expression = true:error + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:error + +# Modifier preferences +csharp_prefer_static_local_function = true:error +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:error + +# Code-block preferences +csharp_prefer_braces = true:error +csharp_prefer_simple_using_statement = true:error + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:error +csharp_style_deconstructed_variable_declaration = true:error +csharp_style_inlined_variable_declaration = true:error +csharp_style_pattern_local_over_anonymous_function = true:error +csharp_style_prefer_index_operator = true:error +csharp_style_prefer_range_operator = true:error +csharp_style_throw_expression = true:error +csharp_style_unused_value_assignment_preference = unused_local_variable:error +csharp_style_unused_value_expression_statement_preference = unused_local_variable:error + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace:error + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = false:error +csharp_new_line_before_else = false:error +csharp_new_line_before_finally = false:error +csharp_new_line_before_members_in_anonymous_types = true:error +csharp_new_line_before_members_in_object_initializers = true:error +csharp_new_line_before_open_brace = none:error +csharp_new_line_between_query_expression_clauses = true:error + +# Indentation preferences +csharp_indent_block_contents = true:error +csharp_indent_braces = false:error +csharp_indent_case_contents = true:error +csharp_indent_case_contents_when_block = true:error +csharp_indent_labels = one_less_than_current:error +csharp_indent_switch_labels = true:error + +# Space preferences +csharp_space_after_cast = false:error +csharp_space_after_colon_in_inheritance_clause = true:error +csharp_space_after_comma = true:error +csharp_space_after_dot = false:error +csharp_space_after_keywords_in_control_flow_statements = true:error +csharp_space_after_semicolon_in_for_statement = true:error +csharp_space_around_binary_operators = before_and_after:error +csharp_space_around_declaration_statements = false:error +csharp_space_before_colon_in_inheritance_clause = false:error +csharp_space_before_comma = false:error +csharp_space_before_dot = false:error +csharp_space_before_open_square_brackets = false:error +csharp_space_before_semicolon_in_for_statement = false:error +csharp_space_between_empty_square_brackets = false:error +csharp_space_between_method_call_empty_parameter_list_parentheses = false:error +csharp_space_between_method_call_name_and_opening_parenthesis = false:error +csharp_space_between_method_call_parameter_list_parentheses = false:error +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false:error +csharp_space_between_method_declaration_name_and_open_parenthesis = false:error +csharp_space_between_method_declaration_parameter_list_parentheses = false:error +csharp_space_between_parentheses = false:error +csharp_space_between_square_brackets = false:error + +# Wrapping preferences +csharp_preserve_single_line_blocks = true:error +csharp_preserve_single_line_statements = true:error + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = error +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = error +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = error +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +### Microsoft.CodeAnalysis.Analyzers Rules + +# RS1001: Missing diagnostic analyzer attribute +dotnet_diagnostic.RS1001.severity = error + +# RS1002: Missing kind argument when registering an analyzer action +dotnet_diagnostic.RS1002.severity = error + +# RS1003: Unsupported SymbolKind argument when registering a symbol analyzer action +dotnet_diagnostic.RS1003.severity = error + +# RS1004: Recommend adding language support to diagnostic analyzer +dotnet_diagnostic.RS1004.severity = error + +# RS1005: ReportDiagnostic invoked with an unsupported DiagnosticDescriptor +dotnet_diagnostic.RS1005.severity = error + +# RS1006: Invalid type argument for DiagnosticAnalyzer's Register method +dotnet_diagnostic.RS1006.severity = error + +# RS1007: Provide localizable arguments to diagnostic descriptor constructor +dotnet_diagnostic.RS1007.severity = error + +# RS1008: Avoid storing per-compilation data into the fields of a diagnostic analyzer +dotnet_diagnostic.RS1008.severity = error + +# RS1009: Only internal implementations of this interface are allowed +dotnet_diagnostic.RS1009.severity = error + +# RS1010: Create code actions should have a unique EquivalenceKey for FixAll occurrences support +dotnet_diagnostic.RS1010.severity = error + +# RS1011: Use code actions that have a unique EquivalenceKey for FixAll occurrences support +dotnet_diagnostic.RS1011.severity = error + +# RS1012: Start action has no registered actions +dotnet_diagnostic.RS1012.severity = error + +# RS1013: Start action has no registered non-end actions +dotnet_diagnostic.RS1013.severity = error + +# RS1014: Do not ignore values returned by methods on immutable objects. +dotnet_diagnostic.RS1014.severity = error + +# RS1015: Provide non-null 'helpLinkUri' value to diagnostic descriptor constructor +dotnet_diagnostic.RS1015.severity = error + +# RS1016: Code fix providers should provide FixAll support +dotnet_diagnostic.RS1016.severity = error + +# RS1017: DiagnosticId for analyzers must be a non-null constant +dotnet_diagnostic.RS1017.severity = error + +# RS1018: DiagnosticId for analyzers must be in specified format +dotnet_diagnostic.RS1018.severity = error + +# RS1019: DiagnosticId must be unique across analyzers +dotnet_diagnostic.RS1019.severity = error + +# RS1020: Category for analyzers must be from the specified values +dotnet_diagnostic.RS1020.severity = error + +# RS1021: Invalid entry in analyzer category and diagnostic ID range specification file +dotnet_diagnostic.RS1021.severity = error + +# RS1022: Do not use types from Workspaces assembly in an analyzer +dotnet_diagnostic.RS1022.severity = error + +# RS1023: Upgrade MSBuildWorkspace +dotnet_diagnostic.RS1023.severity = error + +# RS1024: Compare symbols correctly +dotnet_diagnostic.RS1024.severity = error + +# RS1025: Configure generated code analysis +dotnet_diagnostic.RS1025.severity = error + +# RS1026: Enable concurrent execution +dotnet_diagnostic.RS1026.severity = error + +# RS1027: Types marked with DiagnosticAnalyzerAttribute(s) should inherit from DiagnosticAnalyzer +dotnet_diagnostic.RS1027.severity = error + +# RS1028: Provide non-null 'customTags' value to diagnostic descriptor constructor +dotnet_diagnostic.RS1028.severity = error + +# RS1029: Do not use reserved diagnostic IDs +dotnet_diagnostic.RS1029.severity = error + +# RS1030: Do not invoke Compilation.GetSemanticModel() method within a diagnostic analyzer +dotnet_diagnostic.RS1030.severity = error + +# RS1031: Define diagnostic title correctly +dotnet_diagnostic.RS1031.severity = error + +# RS1032: Define diagnostic message correctly +dotnet_diagnostic.RS1032.severity = error + +# RS1033: Define diagnostic description correctly +dotnet_diagnostic.RS1033.severity = error + +# RS2000: Add analyzer diagnostic IDs to analyzer release. +dotnet_diagnostic.RS2000.severity = error + +# RS2001: Ensure up-to-date entry for analyzer diagnostic IDs are added to analyzer release. +dotnet_diagnostic.RS2001.severity = error + +# RS2002: Do not add removed analyzer diagnostic IDs to unshipped analyzer release. +dotnet_diagnostic.RS2002.severity = error + +# RS2003: Shipped diagnostic IDs that are no longer reported should have an entry in the 'Removed Rules' table in unshipped file. +dotnet_diagnostic.RS2003.severity = error + +# RS2004: Diagnostic IDs marked as removed in analyzer release file should not be reported by analyzers. +dotnet_diagnostic.RS2004.severity = error + +# RS2005: Remove duplicate entries for diagnostic ID in the same analyzer release. +dotnet_diagnostic.RS2005.severity = error + +# RS2006: Remove duplicate entries for diagnostic ID between analyzer releases. +dotnet_diagnostic.RS2006.severity = error + +# RS2007: Invalid entry in analyzer release file. +dotnet_diagnostic.RS2007.severity = error + +# RS2008: Enable analyzer release tracking +dotnet_diagnostic.RS2008.severity = error + +### Microsoft.CodeAnalysis.FxCopAnalyzers Rules + +# CA1058: Types should not extend certain base types +dotnet_diagnostic.CA1058.severity = error + +# CA2153: Do Not Catch Corrupted State Exceptions +dotnet_diagnostic.CA2153.severity = error + +# CA3075: Insecure DTD processing in XML +dotnet_diagnostic.CA3075.severity = error + +# CA3076: Insecure XSLT script processing. +dotnet_diagnostic.CA3076.severity = error + +# CA3077: Insecure Processing in API Design, XmlDocument and XmlTextReader +dotnet_diagnostic.CA3077.severity = error + +# CA3147: Mark Verb Handlers With Validate Antiforgery Token +dotnet_diagnostic.CA3147.severity = error + +### Microsoft.CodeAnalysis.VersionCheckAnalyzer Rules + +# CA9999: Analyzer version mismatch +dotnet_diagnostic.CA9999.severity = error + +### Microsoft.CodeQuality.Analyzers Rules + +# CA1000: Do not declare static members on generic types +dotnet_diagnostic.CA1000.severity = error + +# CA1001: Types that own disposable fields should be disposable +dotnet_diagnostic.CA1001.severity = error + +# CA1002: Do not expose generic lists +dotnet_diagnostic.CA1002.severity = error + +# CA1003: Use generic event handler instances +dotnet_diagnostic.CA1003.severity = error + +# CA1005: Avoid excessive parameters on generic types +dotnet_diagnostic.CA1005.severity = error + +# CA1008: Enums should have zero value +dotnet_diagnostic.CA1008.severity = error + +# CA1010: Generic interface should also be implemented +dotnet_diagnostic.CA1010.severity = error + +# CA1012: Abstract types should not have public constructors +dotnet_diagnostic.CA1012.severity = error + +# CA1014: Mark assemblies with CLSCompliant +dotnet_diagnostic.CA1014.severity = error + +# CA1016: Mark assemblies with assembly version +dotnet_diagnostic.CA1016.severity = error + +# CA1017: Mark assemblies with ComVisible +dotnet_diagnostic.CA1017.severity = error + +# CA1018: Mark attributes with AttributeUsageAttribute +dotnet_diagnostic.CA1018.severity = error + +# CA1019: Define accessors for attribute arguments +dotnet_diagnostic.CA1019.severity = error + +# CA1021: Avoid out parameters +dotnet_diagnostic.CA1021.severity = error + +# CA1024: Use properties where appropriate +dotnet_diagnostic.CA1024.severity = error + +# CA1027: Mark enums with FlagsAttribute +dotnet_diagnostic.CA1027.severity = error + +# CA1028: Enum Storage should be Int32 +dotnet_diagnostic.CA1028.severity = error + +# CA1030: Use events where appropriate +dotnet_diagnostic.CA1030.severity = error + +# CA1031: Do not catch general exception types +dotnet_diagnostic.CA1031.severity = error + +# CA1032: Implement standard exception constructors +dotnet_diagnostic.CA1032.severity = error + +# CA1033: Interface methods should be callable by child types +dotnet_diagnostic.CA1033.severity = error + +# CA1034: Nested types should not be visible +dotnet_diagnostic.CA1034.severity = none + +# CA1036: Override methods on comparable types +dotnet_diagnostic.CA1036.severity = error + +# CA1040: Avoid empty interfaces +dotnet_diagnostic.CA1040.severity = error + +# CA1041: Provide ObsoleteAttribute message +dotnet_diagnostic.CA1041.severity = error + +# CA1043: Use Integral Or String Argument For Indexers +dotnet_diagnostic.CA1043.severity = error + +# CA1044: Properties should not be write only +dotnet_diagnostic.CA1044.severity = error + +# CA1045: Do not pass types by reference +dotnet_diagnostic.CA1045.severity = error + +# CA1046: Do not overload equality operator on reference types +dotnet_diagnostic.CA1046.severity = error + +# CA1047: Do not declare protected member in sealed type +dotnet_diagnostic.CA1047.severity = error + +# CA1050: Declare types in namespaces +dotnet_diagnostic.CA1050.severity = error + +# CA1051: Do not declare visible instance fields +dotnet_diagnostic.CA1051.severity = error + +# CA1052: Static holder types should be Static or NotInheritable +dotnet_diagnostic.CA1052.severity = error + +# CA1054: URI-like parameters should not be strings +dotnet_diagnostic.CA1054.severity = error + +# CA1055: URI-like return values should not be strings +dotnet_diagnostic.CA1055.severity = error + +# CA1056: URI-like properties should not be strings +dotnet_diagnostic.CA1056.severity = error + +# CA1060: Move pinvokes to native methods class +dotnet_diagnostic.CA1060.severity = error + +# CA1061: Do not hide base class methods +dotnet_diagnostic.CA1061.severity = error + +# CA1062: Validate arguments of public methods +dotnet_diagnostic.CA1062.severity = error + +# CA1063: Implement IDisposable Correctly +dotnet_diagnostic.CA1063.severity = error + +# CA1064: Exceptions should be public +dotnet_diagnostic.CA1064.severity = error + +# CA1065: Do not raise exceptions in unexpected locations +dotnet_diagnostic.CA1065.severity = error + +# CA1066: Implement IEquatable when overriding Object.Equals +dotnet_diagnostic.CA1066.severity = none + +# CA1067: Override Object.Equals(object) when implementing IEquatable<T> +dotnet_diagnostic.CA1067.severity = error + +# CA1068: CancellationToken parameters must come last +dotnet_diagnostic.CA1068.severity = error + +# CA1069: Enums values should not be duplicated +dotnet_diagnostic.CA1069.severity = error + +# CA1070: Do not declare event fields as virtual +dotnet_diagnostic.CA1070.severity = error + +# CA1200: Avoid using cref tags with a prefix +dotnet_diagnostic.CA1200.severity = error + +# CA1501: Avoid excessive inheritance +dotnet_diagnostic.CA1501.severity = error + +# CA1502: Avoid excessive complexity +dotnet_diagnostic.CA1502.severity = error + +# CA1505: Avoid unmaintainable code +dotnet_diagnostic.CA1505.severity = error + +# CA1506: Avoid excessive class coupling +dotnet_diagnostic.CA1506.severity = error + +# CA1507: Use nameof to express symbol names +dotnet_diagnostic.CA1507.severity = error + +# CA1508: Avoid dead conditional code +dotnet_diagnostic.CA1508.severity = error + +# CA1509: Invalid entry in code metrics rule specification file +dotnet_diagnostic.CA1509.severity = error + +# CA1700: Do not name enum values 'Reserved' +dotnet_diagnostic.CA1700.severity = error + +# CA1707: Identifiers should not contain underscores +dotnet_diagnostic.CA1707.severity = error + +# CA1708: Identifiers should differ by more than case +dotnet_diagnostic.CA1708.severity = error + +# CA1710: Identifiers should have correct suffix +dotnet_diagnostic.CA1710.severity = error + +# CA1711: Identifiers should not have incorrect suffix +dotnet_diagnostic.CA1711.severity = error + +# CA1712: Do not prefix enum values with type name +dotnet_diagnostic.CA1712.severity = error + +# CA1713: Events should not have 'Before' or 'After' prefix +dotnet_diagnostic.CA1713.severity = error + +# CA1714: Flags enums should have plural names +dotnet_diagnostic.CA1714.severity = error + +# CA1715: Identifiers should have correct prefix +dotnet_diagnostic.CA1715.severity = error + +# CA1716: Identifiers should not match keywords +dotnet_diagnostic.CA1716.severity = error + +# CA1717: Only FlagsAttribute enums should have plural names +dotnet_diagnostic.CA1717.severity = error + +# CA1720: Identifier contains type name +dotnet_diagnostic.CA1720.severity = error + +# CA1721: Property names should not match get methods +dotnet_diagnostic.CA1721.severity = error + +# CA1724: Type names should not match namespaces +dotnet_diagnostic.CA1724.severity = error + +# CA1725: Parameter names should match base declaration +dotnet_diagnostic.CA1725.severity = none + +# CA1801: Review unused parameters +dotnet_diagnostic.CA1801.severity = error + +# CA1802: Use literals where appropriate +dotnet_diagnostic.CA1802.severity = error + +# CA1805: Do not initialize unnecessarily +dotnet_diagnostic.CA1805.severity = none + +# CA1806: Do not ignore method results +dotnet_diagnostic.CA1806.severity = error + +# CA1812: Avoid uninstantiated internal classes +dotnet_diagnostic.CA1812.severity = error + +# CA1814: Prefer jagged arrays over multidimensional +dotnet_diagnostic.CA1814.severity = error + +# CA1815: Override equals and operator equals on value types +dotnet_diagnostic.CA1815.severity = none + +# CA1819: Properties should not return arrays +dotnet_diagnostic.CA1819.severity = error + +# CA1821: Remove empty Finalizers +dotnet_diagnostic.CA1821.severity = error + +# CA1822: Mark members as static +dotnet_diagnostic.CA1822.severity = error + +# CA1823: Avoid unused private fields +dotnet_diagnostic.CA1823.severity = error + +# CA2007: Consider calling ConfigureAwait on the awaited task +dotnet_diagnostic.CA2007.severity = error + +# CA2011: Avoid infinite recursion +dotnet_diagnostic.CA2011.severity = error + +# CA2109: Review visible event handlers +dotnet_diagnostic.CA2109.severity = error + +# CA2119: Seal methods that satisfy private interfaces +dotnet_diagnostic.CA2119.severity = error + +# CA2200: Rethrow to preserve stack details +dotnet_diagnostic.CA2200.severity = error + +# CA2211: Non-constant fields should not be visible +dotnet_diagnostic.CA2211.severity = error + +# CA2214: Do not call overridable methods in constructors +dotnet_diagnostic.CA2214.severity = error + +# CA2217: Do not mark enums with FlagsAttribute +dotnet_diagnostic.CA2217.severity = error + +# CA2218: Override GetHashCode on overriding Equals +dotnet_diagnostic.CA2218.severity = error + +# CA2219: Do not raise exceptions in finally clauses +dotnet_diagnostic.CA2219.severity = error + +# CA2224: Override Equals on overloading operator equals +dotnet_diagnostic.CA2224.severity = error + +# CA2225: Operator overloads have named alternates +dotnet_diagnostic.CA2225.severity = none + +# CA2226: Operators should have symmetrical overloads +dotnet_diagnostic.CA2226.severity = error + +# CA2227: Collection properties should be read only +dotnet_diagnostic.CA2227.severity = error + +# CA2231: Overload operator equals on overriding value type Equals +dotnet_diagnostic.CA2231.severity = none + +# CA2234: Pass system uri objects instead of strings +dotnet_diagnostic.CA2234.severity = error + +# CA2244: Do not duplicate indexed element initializations +dotnet_diagnostic.CA2244.severity = error + +# CA2245: Do not assign a property to itself +dotnet_diagnostic.CA2245.severity = error + +# CA2246: Assigning symbol and its member in the same statement +dotnet_diagnostic.CA2246.severity = error + +### Microsoft.NetCore.Analyzers Rules + +# CA1303: Do not pass literals as localized parameters +dotnet_diagnostic.CA1303.severity = error + +# CA1304: Specify CultureInfo +dotnet_diagnostic.CA1304.severity = error + +# CA1305: Specify IFormatProvider +dotnet_diagnostic.CA1305.severity = error + +# CA1307: Specify StringComparison +dotnet_diagnostic.CA1307.severity = error + +# CA1308: Normalize strings to uppercase +dotnet_diagnostic.CA1308.severity = error + +# CA1309: Use ordinal stringcomparison +dotnet_diagnostic.CA1309.severity = error + +# CA1401: P/Invokes should not be visible +dotnet_diagnostic.CA1401.severity = error + +# CA1417: Do not use 'OutAttribute' on string parameters for P/Invokes +dotnet_diagnostic.CA1417.severity = error + +# CA1810: Initialize reference type static fields inline +dotnet_diagnostic.CA1810.severity = error + +# CA1813: Avoid unsealed attributes +dotnet_diagnostic.CA1813.severity = error + +# CA1816: Dispose methods should call SuppressFinalize +dotnet_diagnostic.CA1816.severity = error + +# CA1820: Test for empty strings using string length +dotnet_diagnostic.CA1820.severity = error + +# CA1824: Mark assemblies with NeutralResourcesLanguageAttribute +dotnet_diagnostic.CA1824.severity = error + +# CA1825: Avoid zero-length array allocations +dotnet_diagnostic.CA1825.severity = error + +# CA1826: Do not use Enumerable methods on indexable collections +dotnet_diagnostic.CA1826.severity = error + +# CA1827: Do not use Count() or LongCount() when Any() can be used +dotnet_diagnostic.CA1827.severity = error + +# CA1828: Do not use CountAsync() or LongCountAsync() when AnyAsync() can be used +dotnet_diagnostic.CA1828.severity = error + +# CA1829: Use Length/Count property instead of Count() when available +dotnet_diagnostic.CA1829.severity = error + +# CA1830: Prefer strongly-typed Append and Insert method overloads on StringBuilder +dotnet_diagnostic.CA1830.severity = error + +# CA1831: Use AsSpan or AsMemory instead of Range-based indexers when appropriate +dotnet_diagnostic.CA1831.severity = error + +# CA1832: Use AsSpan or AsMemory instead of Range-based indexers when appropriate +dotnet_diagnostic.CA1832.severity = error + +# CA1833: Use AsSpan or AsMemory instead of Range-based indexers when appropriate +dotnet_diagnostic.CA1833.severity = error + +# CA1834: Consider using 'StringBuilder.Append(char)' when applicable +dotnet_diagnostic.CA1834.severity = error + +# CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync' +dotnet_diagnostic.CA1835.severity = error + +# CA1836: Prefer IsEmpty over Count +dotnet_diagnostic.CA1836.severity = error + +# CA1837: Use 'Environment.ProcessId' +dotnet_diagnostic.CA1837.severity = error + +# CA1838: Avoid 'StringBuilder' parameters for P/Invokes +dotnet_diagnostic.CA1838.severity = error + +# CA2000: Dispose objects before losing scope +dotnet_diagnostic.CA2000.severity = error + +# CA2002: Do not lock on objects with weak identity +dotnet_diagnostic.CA2002.severity = error + +# CA2008: Do not create tasks without passing a TaskScheduler +dotnet_diagnostic.CA2008.severity = error + +# CA2009: Do not call ToImmutableCollection on an ImmutableCollection value +dotnet_diagnostic.CA2009.severity = error + +# CA2012: Use ValueTasks correctly +dotnet_diagnostic.CA2012.severity = error + +# CA2013: Do not use ReferenceEquals with value types +dotnet_diagnostic.CA2013.severity = error + +# CA2014: Do not use stackalloc in loops +dotnet_diagnostic.CA2014.severity = error + +# CA2015: Do not define finalizers for types derived from MemoryManager<T> +dotnet_diagnostic.CA2015.severity = error + +# CA2016: Forward the 'CancellationToken' parameter to methods that take one +dotnet_diagnostic.CA2016.severity = error + +# CA2100: Review SQL queries for security vulnerabilities +dotnet_diagnostic.CA2100.severity = error + +# CA2101: Specify marshaling for P/Invoke string arguments +dotnet_diagnostic.CA2101.severity = error + +# CA2201: Do not raise reserved exception types +dotnet_diagnostic.CA2201.severity = error + +# CA2207: Initialize value type static fields inline +dotnet_diagnostic.CA2207.severity = error + +# CA2208: Instantiate argument exceptions correctly +dotnet_diagnostic.CA2208.severity = error + +# CA2213: Disposable fields should be disposed +dotnet_diagnostic.CA2213.severity = error + +# CA2215: Dispose methods should call base class dispose +dotnet_diagnostic.CA2215.severity = error + +# CA2216: Disposable types should declare finalizer +dotnet_diagnostic.CA2216.severity = error + +# CA2229: Implement serialization constructors +dotnet_diagnostic.CA2229.severity = error + +# CA2235: Mark all non-serializable fields +dotnet_diagnostic.CA2235.severity = error + +# CA2237: Mark ISerializable types with serializable +dotnet_diagnostic.CA2237.severity = error + +# CA2241: Provide correct arguments to formatting methods +dotnet_diagnostic.CA2241.severity = error + +# CA2242: Test for NaN correctly +dotnet_diagnostic.CA2242.severity = error + +# CA2243: Attribute string literals should parse correctly +dotnet_diagnostic.CA2243.severity = error + +# CA2247: Argument passed to TaskCompletionSource constructor should be TaskCreationOptions enum instead of TaskContinuationOptions enum +dotnet_diagnostic.CA2247.severity = error + +# CA2248: Provide correct 'enum' argument to 'Enum.HasFlag' +dotnet_diagnostic.CA2248.severity = error + +# CA2249: Consider using 'string.Contains' instead of 'string.IndexOf' +dotnet_diagnostic.CA2249.severity = error + +# CA2300: Do not use insecure deserializer BinaryFormatter +dotnet_diagnostic.CA2300.severity = error + +# CA2301: Do not call BinaryFormatter.Deserialize without first setting BinaryFormatter.Binder +dotnet_diagnostic.CA2301.severity = error + +# CA2302: Ensure BinaryFormatter.Binder is set before calling BinaryFormatter.Deserialize +dotnet_diagnostic.CA2302.severity = error + +# CA2305: Do not use insecure deserializer LosFormatter +dotnet_diagnostic.CA2305.severity = error + +# CA2310: Do not use insecure deserializer NetDataContractSerializer +dotnet_diagnostic.CA2310.severity = error + +# CA2311: Do not deserialize without first setting NetDataContractSerializer.Binder +dotnet_diagnostic.CA2311.severity = error + +# CA2312: Ensure NetDataContractSerializer.Binder is set before deserializing +dotnet_diagnostic.CA2312.severity = error + +# CA2315: Do not use insecure deserializer ObjectStateFormatter +dotnet_diagnostic.CA2315.severity = error + +# CA2321: Do not deserialize with JavaScriptSerializer using a SimpleTypeResolver +dotnet_diagnostic.CA2321.severity = error + +# CA2322: Ensure JavaScriptSerializer is not initialized with SimpleTypeResolver before deserializing +dotnet_diagnostic.CA2322.severity = error + +# CA2326: Do not use TypeNameHandling values other than None +dotnet_diagnostic.CA2326.severity = error + +# CA2327: Do not use insecure JsonSerializerSettings +dotnet_diagnostic.CA2327.severity = error + +# CA2328: Ensure that JsonSerializerSettings are secure +dotnet_diagnostic.CA2328.severity = error + +# CA2329: Do not deserialize with JsonSerializer using an insecure configuration +dotnet_diagnostic.CA2329.severity = error + +# CA2330: Ensure that JsonSerializer has a secure configuration when deserializing +dotnet_diagnostic.CA2330.severity = error + +# CA2350: Do not use DataTable.ReadXml() with untrusted data +dotnet_diagnostic.CA2350.severity = error + +# CA2351: Do not use DataSet.ReadXml() with untrusted data +dotnet_diagnostic.CA2351.severity = error + +# CA2352: Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks +dotnet_diagnostic.CA2352.severity = error + +# CA2353: Unsafe DataSet or DataTable in serializable type +dotnet_diagnostic.CA2353.severity = error + +# CA2354: Unsafe DataSet or DataTable in deserialized object graph can be vulnerable to remote code execution attacks +dotnet_diagnostic.CA2354.severity = error + +# CA2355: Unsafe DataSet or DataTable type found in deserializable object graph +dotnet_diagnostic.CA2355.severity = error + +# CA2356: Unsafe DataSet or DataTable type in web deserializable object graph +dotnet_diagnostic.CA2356.severity = error + +# CA2361: Ensure autogenerated class containing DataSet.ReadXml() is not used with untrusted data +dotnet_diagnostic.CA2361.severity = error + +# CA2362: Unsafe DataSet or DataTable in autogenerated serializable type can be vulnerable to remote code execution attacks +dotnet_diagnostic.CA2362.severity = error + +# CA3001: Review code for SQL injection vulnerabilities +dotnet_diagnostic.CA3001.severity = error + +# CA3002: Review code for XSS vulnerabilities +dotnet_diagnostic.CA3002.severity = error + +# CA3003: Review code for file path injection vulnerabilities +dotnet_diagnostic.CA3003.severity = error + +# CA3004: Review code for information disclosure vulnerabilities +dotnet_diagnostic.CA3004.severity = error + +# CA3005: Review code for LDAP injection vulnerabilities +dotnet_diagnostic.CA3005.severity = error + +# CA3006: Review code for process command injection vulnerabilities +dotnet_diagnostic.CA3006.severity = error + +# CA3007: Review code for open redirect vulnerabilities +dotnet_diagnostic.CA3007.severity = error + +# CA3008: Review code for XPath injection vulnerabilities +dotnet_diagnostic.CA3008.severity = error + +# CA3009: Review code for XML injection vulnerabilities +dotnet_diagnostic.CA3009.severity = error + +# CA3010: Review code for XAML injection vulnerabilities +dotnet_diagnostic.CA3010.severity = error + +# CA3011: Review code for DLL injection vulnerabilities +dotnet_diagnostic.CA3011.severity = error + +# CA3012: Review code for regex injection vulnerabilities +dotnet_diagnostic.CA3012.severity = error + +# CA3061: Do Not Add Schema By URL +dotnet_diagnostic.CA3061.severity = error + +# CA5350: Do Not Use Weak Cryptographic Algorithms +dotnet_diagnostic.CA5350.severity = error + +# CA5351: Do Not Use Broken Cryptographic Algorithms +dotnet_diagnostic.CA5351.severity = error + +# CA5358: Review cipher mode usage with cryptography experts +dotnet_diagnostic.CA5358.severity = error + +# CA5359: Do Not Disable Certificate Validation +dotnet_diagnostic.CA5359.severity = error + +# CA5360: Do Not Call Dangerous Methods In Deserialization +dotnet_diagnostic.CA5360.severity = error + +# CA5361: Do Not Disable SChannel Use of Strong Crypto +dotnet_diagnostic.CA5361.severity = error + +# CA5362: Potential reference cycle in deserialized object graph +dotnet_diagnostic.CA5362.severity = error + +# CA5363: Do Not Disable Request Validation +dotnet_diagnostic.CA5363.severity = error + +# CA5364: Do Not Use Deprecated Security Protocols +dotnet_diagnostic.CA5364.severity = error + +# CA5365: Do Not Disable HTTP Header Checking +dotnet_diagnostic.CA5365.severity = error + +# CA5366: Use XmlReader For DataSet Read Xml +dotnet_diagnostic.CA5366.severity = error + +# CA5367: Do Not Serialize Types With Pointer Fields +dotnet_diagnostic.CA5367.severity = error + +# CA5368: Set ViewStateUserKey For Classes Derived From Page +dotnet_diagnostic.CA5368.severity = error + +# CA5369: Use XmlReader For Deserialize +dotnet_diagnostic.CA5369.severity = error + +# CA5370: Use XmlReader For Validating Reader +dotnet_diagnostic.CA5370.severity = error + +# CA5371: Use XmlReader For Schema Read +dotnet_diagnostic.CA5371.severity = error + +# CA5372: Use XmlReader For XPathDocument +dotnet_diagnostic.CA5372.severity = error + +# CA5373: Do not use obsolete key derivation function +dotnet_diagnostic.CA5373.severity = error + +# CA5374: Do Not Use XslTransform +dotnet_diagnostic.CA5374.severity = error + +# CA5375: Do Not Use Account Shared Access Signature +dotnet_diagnostic.CA5375.severity = error + +# CA5376: Use SharedAccessProtocol HttpsOnly +dotnet_diagnostic.CA5376.severity = error + +# CA5377: Use Container Level Access Policy +dotnet_diagnostic.CA5377.severity = error + +# CA5378: Do not disable ServicePointManagerSecurityProtocols +dotnet_diagnostic.CA5378.severity = error + +# CA5379: Do Not Use Weak Key Derivation Function Algorithm +dotnet_diagnostic.CA5379.severity = error + +# CA5380: Do Not Add Certificates To Root Store +dotnet_diagnostic.CA5380.severity = error + +# CA5381: Ensure Certificates Are Not Added To Root Store +dotnet_diagnostic.CA5381.severity = error + +# CA5382: Use Secure Cookies In ASP.Net Core +dotnet_diagnostic.CA5382.severity = error + +# CA5383: Ensure Use Secure Cookies In ASP.Net Core +dotnet_diagnostic.CA5383.severity = error + +# CA5384: Do Not Use Digital Signature Algorithm (DSA) +dotnet_diagnostic.CA5384.severity = error + +# CA5385: Use Rivest–Shamir–Adleman (RSA) Algorithm With Sufficient Key Size +dotnet_diagnostic.CA5385.severity = error + +# CA5386: Avoid hardcoding SecurityProtocolType value +dotnet_diagnostic.CA5386.severity = error + +# CA5387: Do Not Use Weak Key Derivation Function With Insufficient Iteration Count +dotnet_diagnostic.CA5387.severity = error + +# CA5388: Ensure Sufficient Iteration Count When Using Weak Key Derivation Function +dotnet_diagnostic.CA5388.severity = error + +# CA5389: Do Not Add Archive Item's Path To The Target File System Path +dotnet_diagnostic.CA5389.severity = error + +# CA5390: Do not hard-code encryption key +dotnet_diagnostic.CA5390.severity = error + +# CA5391: Use antiforgery tokens in ASP.NET Core MVC controllers +dotnet_diagnostic.CA5391.severity = error + +# CA5392: Use DefaultDllImportSearchPaths attribute for P/Invokes +dotnet_diagnostic.CA5392.severity = error + +# CA5393: Do not use unsafe DllImportSearchPath value +dotnet_diagnostic.CA5393.severity = error + +# CA5394: Do not use insecure randomness +dotnet_diagnostic.CA5394.severity = error + +# CA5395: Miss HttpVerb attribute for action methods +dotnet_diagnostic.CA5395.severity = error + +# CA5396: Set HttpOnly to true for HttpCookie +dotnet_diagnostic.CA5396.severity = error + +# CA5397: Do not use deprecated SslProtocols values +dotnet_diagnostic.CA5397.severity = error + +# CA5398: Avoid hardcoded SslProtocols values +dotnet_diagnostic.CA5398.severity = error + +# CA5399: HttpClients should enable certificate revocation list checks +dotnet_diagnostic.CA5399.severity = error + +# CA5400: Ensure HttpClient certificate revocation list check is not disabled +dotnet_diagnostic.CA5400.severity = error + +# CA5401: Do not use CreateEncryptor with non-default IV +dotnet_diagnostic.CA5401.severity = error + +# CA5402: Use CreateEncryptor with the default IV +dotnet_diagnostic.CA5402.severity = error + +# CA5403: Do not hard-code certificate +dotnet_diagnostic.CA5403.severity = error + +# IL3000: Avoid using accessing Assembly file path when publishing as a single-file +dotnet_diagnostic.IL3000.severity = error + +# IL3001: Avoid using accessing Assembly file path when publishing as a single-file +dotnet_diagnostic.IL3001.severity = error + +# IDE0071: String interpolation can be simplified +dotnet_diagnostic.IDE0071.severity = none + +# IDE0064: Make readonly fields writable +dotnet_diagnostic.IDE0064.severity = error +\ No newline at end of file diff --git a/.gitignore b/.gitignore @@ -0,0 +1,2 @@ +bin/** +obj/** diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System; +using System.Reflection; + +[assembly: AssemblyCulture("")] +[assembly: AssemblyDefaultAlias("XXHash")] +[assembly: AssemblyTrademark("")] +[assembly: CLSCompliant(false)] +\ No newline at end of file diff --git a/Hasher.cs b/Hasher.cs @@ -0,0 +1,393 @@ +using Std; +using Std.Clone; +using Std.Convert; +using Std.Hashing; +using Std.Maybe; +using Std.Num; +using Std.Result; +using System; +using System.Runtime.CompilerServices; +using System.Security.Cryptography; +using System.Runtime.InteropServices; +#region Namespaces +namespace XXHash { + #region Types + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)] + struct Buffer: IClone<Buffer>, IInto<Buffer> { + + #region Type-level Constructors + #endregion + + #region Instance Constructors + public Buffer() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!"); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + Buffer(byte[] data, ulong len) => (_data, _len) = (data, len); + #endregion + + #region Type-level Fields + #endregion + + #region Instance Fields + readonly byte[] _data; + internal ulong _len; + #endregion + + #region Type-level Properties + #endregion + + #region Instance Properties + #endregion + + #region Type-level Functions + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Buffer Default() => new(new byte[Functions.CHUNK_SIZE], ulong.MinValue); + #endregion + + #region Instance Functions + [MethodImpl(MethodImplOptions.AggressiveInlining)] + readonly ulong Available() => Functions.CHUNK_SIZE - _len; + public readonly Buffer Clone() { + + var data = new byte[_data.Length]; + + for (var i = 0; i < data.Length; i++) { + data[i] = _data[i]; + } + return new(data, _len); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal ReadOnlySpan<byte> Consume(ReadOnlySpan<byte> data) { + + var toUse = Math.Min(Available(), (ulong)data.Length); + var remaining = data[(int)toUse..]; + data = data[..(int)toUse]; + var len = (int)_len; + + for (var i = 0; i < (int)toUse; i++) { + _data[len + i] = data[i]; + } + _len += toUse; + return remaining; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal readonly ReadOnlySpan<byte> Data() => _data.AsSpan(0, (int)_len); + public override readonly bool Equals(object? _) => false; + public override readonly int GetHashCode() => 0; + public readonly Buffer Into() => this; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal readonly bool IsEmpty() => _len == ulong.MinValue; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal readonly bool IsFull() => _len == Functions.CHUNK_SIZE; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Unit SetData(ReadOnlySpan<byte> data) { + System.Diagnostics.Debug.Assert(IsEmpty()); + System.Diagnostics.Debug.Assert(data.Length < (int)Functions.CHUNK_SIZE); + + for (var i = 0; i < data.Length; i++) { + _data[i] = data[i]; + } + _len = (ulong)data.Length; + return new Unit(); + } + public override readonly string ToString() => string.Empty; + readonly Result<Buffer, Bottom> ITryInto<Buffer, Bottom>.TryInto() => new(this); + #endregion + + #region Operators + #endregion + + #region Types + #endregion + } + [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Pack = 8, Size = 8)] + public readonly struct RandomXXHashBuilder: IBuildHasher<XXHasher>, IClone<RandomXXHashBuilder>, IInto<RandomXXHashBuilder> { + + #region Type-level Constructors + #endregion + + #region Instance Constructors + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public RandomXXHashBuilder() => _seed = ulong.MinValue; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + RandomXXHashBuilder(ulong seed) => _seed = seed; + #endregion + + #region Type-level Fields + #endregion + + #region Instance Fields + [FieldOffset(0)]readonly ulong _seed; + #endregion + + #region Type-level Properties + #endregion + + #region Instance Properties + #endregion + + #region Type-level Functions + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static RandomXXHashBuilder New() { + + Span<byte> key = stackalloc byte[8]; + RandomNumberGenerator.Fill(key); + return new(BitConverter.ToUInt64(key)); + } + #endregion + + #region Instance Functions + public readonly XXHasher BuildHasher() => XXHasher.WithSeed(_seed); + public readonly RandomXXHashBuilder Clone() => this; + public override readonly bool Equals(object? _) => false; + public override readonly int GetHashCode() => 0; + public readonly RandomXXHashBuilder Into() => this; + public override readonly string ToString() => "RandomXXHashBuilder"; + readonly Result<RandomXXHashBuilder, Bottom> ITryInto<RandomXXHashBuilder, Bottom>.TryInto() => new(this); + #endregion + + #region Operators + #endregion + + #region Types + #endregion + } + [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Pack = 8, Size = 32)] + struct XxCore: IClone<XxCore>, IInto<XxCore> { + + #region Type-level Constructors + #endregion + + #region Instance Constructors + public XxCore() => throw new InvalidOperationException("Parameterless constructor is not allowed to be called!"); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + XxCore(ulong v1, ulong v2, ulong v3, ulong v4) => (_v1, _v2, _v3, _v4) = (v1, v2, v3, v4); + #endregion + + #region Type-level Fields + #endregion + + #region Instance Fields + [FieldOffset(0)] ulong _v1; + [FieldOffset(8)] ulong _v2; + [FieldOffset(16)] ulong _v3; + [FieldOffset(24)] ulong _v4; + #endregion + + #region Type-level Properties + #endregion + + #region Instance Properties + #endregion + + #region Type-level Functions + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static XxCore WithSeed(ulong seed) => new(seed + Functions.PRIME_1 + Functions.PRIME_2, seed + Functions.PRIME_2, seed, seed - Functions.PRIME_1); + #endregion + + #region Instance Functions + public readonly XxCore Clone() => this; + public override readonly bool Equals(object? _) => false; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal readonly ulong Finish() { + + var hash = _v1.RotateLeft(1u) + _v2.RotateLeft(7u) + _v3.RotateLeft(12u) + _v4.RotateLeft(18u); + static ulong MixOne(ulong hash, ulong value) => ((hash ^ ((value * Functions.PRIME_2).RotateLeft(31u) * Functions.PRIME_1)) * Functions.PRIME_1) + Functions.PRIME_4; + hash = MixOne(hash, _v1); + hash = MixOne(hash, _v2); + hash = MixOne(hash, _v3); + hash = MixOne(hash, _v4); + return hash; + } + public override readonly int GetHashCode() => 0; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Unit IngestChunks(ref UnalignedBuffer values) { + + static ulong IngestOneNumber(ulong currentValue, ulong value) => (currentValue + (value * Functions.PRIME_2)).RotateLeft(31u) * Functions.PRIME_1; + var (v1, v2, v3, v4) = (_v1, _v2, _v3, _v4); + var next = values.Next4UlongReadOnlySpan(out var exists); + + while (exists) { + v1 = IngestOneNumber(v1, next[0]); + v2 = IngestOneNumber(v2, next[1]); + v3 = IngestOneNumber(v3, next[2]); + v4 = IngestOneNumber(v4, next[3]); + next = values.Next4UlongReadOnlySpan(out exists); + } + (_v1, _v2, _v3, _v4) = (v1, v2, v3, v4); + return new Unit(); + } + public readonly XxCore Into() => this; + public override readonly string ToString() => string.Empty; + readonly Result<XxCore, Bottom> ITryInto<XxCore, Bottom>.TryInto() => new(this); + #endregion + + #region Operators + #endregion + + #region Types + #endregion + } + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 0)] + public struct XXHasher: IClone<XXHasher>, IHasher, IInto<XXHasher> { + + #region Type-level Constructors + #endregion + + #region Instance Constructors + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public XXHasher() => (_totalLen, _seed, _core, _buffer) = (ulong.MinValue, ulong.MinValue, XxCore.WithSeed(ulong.MinValue), Buffer.Default()); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public XXHasher(ulong seed) => (_totalLen, _seed, _core, _buffer) = (ulong.MinValue, seed, XxCore.WithSeed(seed), Buffer.Default()); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + XXHasher(ulong totalLen, ulong seed, XxCore core, Buffer buffer) => (_totalLen, _seed, _core, _buffer) = (totalLen, seed, core, buffer); + #endregion + + #region Type-level Fields + #endregion + + #region Instance Fields + XxCore _core; + Buffer _buffer; + ulong _totalLen; + readonly ulong _seed; + #endregion + + #region Type-level Properties + #endregion + + #region Instance Properties + #endregion + + #region Type-level Functions + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static XXHasher WithSeed(ulong seed) => new(ulong.MinValue, seed, XxCore.WithSeed(seed), Buffer.Default()); + #endregion + + #region Instance Functions + public readonly XXHasher Clone() => new(_totalLen, _seed, _core.Clone(), _buffer.Clone()); + public override readonly bool Equals(object? _) => false; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public readonly ulong Finish() { + + var hash = (_totalLen >= Functions.CHUNK_SIZE ? _core.Finish() : _seed + Functions.PRIME_5) + _totalLen; + var bufferedUlongs = UnalignedBuffer.New(_buffer.Data()); + Maybe<ulong> bufferedUlong; + + while ((bufferedUlong = bufferedUlongs.NextUlong()).IsSome) { + hash = ((hash ^ ((bufferedUlong.Unwrap() * Functions.PRIME_2).RotateLeft(31u) * Functions.PRIME_1)).RotateLeft(27u) * Functions.PRIME_1) + Functions.PRIME_4; + } + var bufferedUints = UnalignedBuffer.New(bufferedUlongs.Remaining()); + Maybe<uint> bufferedUint; + + while ((bufferedUint = bufferedUints.NextUint()).IsSome) { + hash = ((hash ^ (bufferedUint.Unwrap() * Functions.PRIME_1)).RotateLeft(23u) * Functions.PRIME_2) + Functions.PRIME_3; + } + var bufferedBytes = bufferedUints.Remaining(); + + for (var i = 0; i < bufferedBytes.Length; i++) { + hash = (hash ^ (bufferedBytes[i] * Functions.PRIME_5)).RotateLeft(11u) * Functions.PRIME_1; + } + hash = (hash ^ (hash >> 33)) * Functions.PRIME_2; + hash = (hash ^ (hash >> 29)) * Functions.PRIME_3; + return hash ^ (hash >> 32); + } + public override readonly int GetHashCode() => 0; + public readonly XXHasher Into() => this; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + ReadOnlySpan<byte> MaybeConsumeBytes(ReadOnlySpan<byte> data) { + + if (_buffer.IsEmpty()) { + return data; + } else { + data = _buffer.Consume(data); + + if (_buffer.IsFull()) { + var ulongs = UnalignedBuffer.New(_buffer.Data()); + _ = _core.IngestChunks(ref ulongs); + System.Diagnostics.Debug.Assert(ulongs.Remaining().IsEmpty); + _buffer._len = ulong.MinValue; + } + return data; + } + } + public override readonly string ToString() => string.Empty; + readonly Result<XXHasher, Bottom> ITryInto<XXHasher, Bottom>.TryInto() => new(this); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Unit WriteUnsafe<T>(T val) where T: unmanaged => IHasher.WriteDefaultUnsafe(ref this, val); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Unit Write(ReadOnlySpan<byte> bytes) { + + var remaining = MaybeConsumeBytes(bytes); + + if (!remaining.IsEmpty) { + var rem2 = UnalignedBuffer.New(remaining); + _ = _core.IngestChunks(ref rem2); + _ = _buffer.SetData(rem2.Remaining()); + } + _totalLen += (ulong)bytes.Length; + return new Unit(); + } + public Unit WriteByte(byte val) => IHasher.WriteByteDefault(ref this, val); + public Unit WriteI128(I128 val) => IHasher.WriteI128Default(ref this, val); + public Unit WriteInt(int val) => IHasher.WriteIntDefault(ref this, val); + public Unit WriteLong(long val) => IHasher.WriteLongDefault(ref this, val); + public Unit WriteSbyte(sbyte val) => IHasher.WriteSbyteDefault(ref this, val); + public Unit WriteShort(short val) => IHasher.WriteShortDefault(ref this, val); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Unit WriteSliceUnsafe<T>(ReadOnlySpan<T> val) where T: unmanaged => IHasher.WriteSliceDefaultUnsafe(ref this, val); + public Unit WriteU128(U128 val) => IHasher.WriteU128Default(ref this, val); + public Unit WriteUint(uint val) => IHasher.WriteUintDefault(ref this, val); + public Unit WriteUlong(ulong val) => IHasher.WriteUlongDefault(ref this, val); + public Unit WriteUshort(ushort val) => IHasher.WriteUshortDefault(ref this, val); + #endregion + + #region Operators + #endregion + + #region Types + #endregion + } + static class Functions { + + #region Type-level Constructors + #endregion + + #region Instance Constructors + #endregion + + #region Type-level Fields + internal const ulong CHUNK_SIZE = 32ul; + internal const ulong PRIME_1 = 11_400_714_785_074_694_791ul; + internal const ulong PRIME_2 = 14_029_467_366_897_019_727ul; + internal const ulong PRIME_3 = 1_609_587_929_392_839_161ul; + internal const ulong PRIME_4 = 9_650_029_242_287_828_579ul; + internal const ulong PRIME_5 = 2_870_177_450_012_600_261ul; + #endregion + + #region Instance Fields + #endregion + + #region Type-level Properties + #endregion + + #region Instance Properties + #endregion + + #region Type-level Functions + #endregion + + #region Instance Functions + #endregion + + #region Operators + #endregion + + #region Types + #endregion + } + #endregion + + #region Namespaces + #endregion +} +#endregion diff --git a/LICENSE-APACHE b/LICENSE-APACHE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/LICENSE-MIT b/LICENSE-MIT @@ -0,0 +1,20 @@ +Copyright © 2023 Zack Newman + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +“Software”), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Lib.cs b/Lib.cs @@ -0,0 +1,99 @@ +using Std.Maybe; +using System; +using System.Runtime.CompilerServices; +#region Namespaces +namespace XXHash { + #region Types + ref struct UnalignedBuffer { + + #region Type-level Constructors + #endregion + + #region Instance Constructors + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public UnalignedBuffer() => _buf = ReadOnlySpan<byte>.Empty; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + UnalignedBuffer(ReadOnlySpan<byte> buf) => _buf = buf; + #endregion + + #region Type-level Fields + #endregion + + #region Instance Fields + ReadOnlySpan<byte> _buf; + #endregion + + #region Type-level Properties + #endregion + + #region Instance Properties + #endregion + + #region Type-level Functions + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static UnalignedBuffer New(ReadOnlySpan<byte> buf) => new(buf); + #endregion + + #region Instance Functions + public override readonly bool Equals(object? _) => false; + public override readonly int GetHashCode() => 0; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal ReadOnlySpan<ulong> Next4UlongReadOnlySpan(out bool exists) { + + if (_buf.Length >= 32) { + unsafe { + fixed (byte* ptr = _buf) { + exists = true; + _buf = _buf[32..]; + return new ReadOnlySpan<ulong>((ulong*)ptr, 4); + } + } + } else { + exists = false; + return ReadOnlySpan<ulong>.Empty; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Maybe<uint> NextUint() { + + if (_buf.Length >= 4) { + unsafe { + fixed (byte* ptr = _buf) { + _buf = _buf[4..]; + return new(*(uint*)ptr); + } + } + } else { + return Maybe<uint>.None(); + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Maybe<ulong> NextUlong() { + + if (_buf.Length >= 8) { + unsafe { + fixed (byte* ptr = _buf) { + _buf = _buf[8..]; + return new(*(ulong*)ptr); + } + } + } else { + return Maybe<ulong>.None(); + } + }[MethodImpl(MethodImplOptions.AggressiveInlining)] + internal readonly ReadOnlySpan<byte> Remaining() => _buf; + public override readonly string ToString() => string.Empty; + #endregion + + #region Operators + #endregion + + #region Types + #endregion + } + #endregion + + #region Namespaces + #endregion +} +#endregion diff --git a/README.md b/README.md @@ -0,0 +1,3 @@ +XXHash +-------- +Port of Rust's twox-hash crate. diff --git a/XXHash.csproj b/XXHash.csproj @@ -0,0 +1,61 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + <AnalysisLevel>latest</AnalysisLevel> + <AnalysisMode>All</AnalysisMode> + <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> + <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> + <AssemblyName>XXHash</AssemblyName> + <AssemblyTitle>XXHash</AssemblyTitle> + <AssemblyVersion>1.0.0.0</AssemblyVersion> + <Authors>Zack Newman</Authors> + <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow> + <CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors> + <Company>Philomathic Life</Company> + <Configuration>Release</Configuration> + <Copyright>2023</Copyright> + <DebugSymbols>false</DebugSymbols> + <DebugType>none</DebugType> + <DefineConstants></DefineConstants> + <Description>Hasher based on xxHash.</Description> + <Deterministic>true</Deterministic> + <DocumentationFile></DocumentationFile> + <EnableComHosting>false</EnableComHosting> + <EnableDynamicLoading>false</EnableDynamicLoading> + <EnableNETAnalyzers>true</EnableNETAnalyzers> + <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild> + <ErrorReport>prompt</ErrorReport> + <FileAlignment>512</FileAlignment> + <FileVersion>1.0.0.0</FileVersion> + <HighEntropyVA>true</HighEntropyVA> + <InformationalVersion>1.0.0.0</InformationalVersion> + <IsTrimmable>true</IsTrimmable> + <LangVersion>latest</LangVersion> + <NeutralLanguage>en-US</NeutralLanguage> + <NoWarn></NoWarn> + <Nullable>enable</Nullable> + <Optimize>true</Optimize> + <OutputPath>bin/Release</OutputPath> + <OutputType>Library</OutputType> + <Platform>x64</Platform> + <Product>XXHash</Product> + <PublishTrimmed>true</PublishTrimmed> + <RuntimeIdentifier>linux-x64</RuntimeIdentifier> + <TargetFramework>net7.0</TargetFramework> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + <TrimMode>link</TrimMode> + <TrimmerDefaultAction>link</TrimmerDefaultAction> + <Utf8Output>true</Utf8Output> + <WarningsAsErrors>true</WarningsAsErrors> + </PropertyGroup> + + <ItemGroup> + <Reference Include="Std"> + <Name>Std</Name> + <HintPath>../Std/bin/Release/Std.dll</HintPath> + <Private>false</Private> + </Reference> + </ItemGroup> + +</Project>