Rename because it is ordered
This commit is contained in:
parent
b5b363ae9f
commit
e3cec3423b
28 changed files with 104 additions and 104 deletions
67
PersistentOrderedMap/KeyStrategies.cs
Normal file
67
PersistentOrderedMap/KeyStrategies.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
|
||||
namespace PersistentOrderedMap;
|
||||
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
public interface IKeyStrategy<K>
|
||||
{
|
||||
int Compare(K x, K y);
|
||||
long GetPrefix(K key);
|
||||
|
||||
bool UsesPrefixes => true;
|
||||
|
||||
bool IsLossless => false;
|
||||
bool UseBinarySearch => false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public struct UnicodeStrategy : IKeyStrategy<string>
|
||||
{
|
||||
|
||||
public bool UsesPrefixes => true;
|
||||
public bool UseBinarySearch => false;
|
||||
public bool IsLossLess => false;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int Compare(string? x, string? y) => string.CompareOrdinal(x, y);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public long GetPrefix(string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key)) return long.MinValue;
|
||||
|
||||
// 1. Prepare Buffer (8 bytes)
|
||||
// stackalloc is virtually free (pointer bump)
|
||||
Span<byte> utf8Bytes = stackalloc byte[8];
|
||||
|
||||
// 2. Transcode (The "Safe" Magic)
|
||||
// This intrinsic handles ASCII efficiently and converts Surrogates/Chinese
|
||||
// into bytes that maintain the correct "Magnitude" (Sort Order).
|
||||
// Invalid surrogates become 0xEF (Replacement Char), which sorts > ASCII.
|
||||
System.Text.Unicode.Utf8.FromUtf16(
|
||||
key.AsSpan(0, Math.Min(key.Length, 8)),
|
||||
utf8Bytes,
|
||||
out _,
|
||||
out _,
|
||||
replaceInvalidSequences: true); // True ensures we get 0xEF for broken chars
|
||||
|
||||
// 3. Load as Big Endian Long
|
||||
long packed = BinaryPrimitives.ReadInt64BigEndian(utf8Bytes);
|
||||
|
||||
// 4. Sign Toggle
|
||||
// Maps the byte range 0x00..0xFF to the signed long range Min..Max
|
||||
// Essential for the < and > operators to work correctly.
|
||||
return packed ^ unchecked((long)0x8080808080808080);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue