我有一个类似的问题,增加了警告,我也想支持RowKey按降序排序。在我的情况下,我并不在乎支持数万亿的可能值,因为我正确使用了PartitionKey,并且还需要在需要进一步细分RowKey时使用范围前缀(如“scope-id” - >“12-8374”)。最后我决定了enzi提出的一般方法的具体实现。我使用了Base64编码的修改版本,生成一个四个字符的字符串,它支持超过1600万个值,并可按升序或降序排序。这是代码,它已经过单元测试,但缺少范围检查/验证。
/// <summary>
/// Gets the four character string representation of the specified integer id.
/// </summary>
/// <param name="number">The number to convert</param>
/// <param name="ascending">Indicates whether the encoded number will be sorted ascending or descending</param>
/// <returns>The encoded string representation of the number</returns>
public static string NumberToId(int number, bool ascending = true)
{
if (!ascending)
number = 16777215 - number;
return new string(new[] {
SixBitToChar((byte)((number & 16515072) >> 18)),
SixBitToChar((byte)((number & 258048) >> 12)),
SixBitToChar((byte)((number & 4032) >> 6)),
SixBitToChar((byte)(number & 63)) });
}
/// <summary>
/// Gets the numeric identifier represented by the encoded string.
/// </summary>
/// <param name="id">The encoded string to convert</param>
/// <param name="ascending">Indicates whether the encoded number is sorted ascending or descending</param>
/// <returns>The decoded integer id</returns>
public static int IdToNumber(string id, bool ascending = true)
{
var number = ((int)CharToSixBit(id[0]) << 18) | ((int)CharToSixBit(id[1]) << 12) | ((int)CharToSixBit(id[2]) << 6) | (int)CharToSixBit(id[3]);
return ascending ? number : -1 * (number - 16777215);
}
/// <summary>
/// Converts the specified byte (representing 6 bits) to the correct character representation.
/// </summary>
/// <param name="b">The bits to convert</param>
/// <returns>The encoded character value</returns>
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
static char SixBitToChar(byte b)
{
if (b == 0)
return '!';
if (b == 1)
return '$';
if (b < 12)
return (char)((int)b - 2 + (int)'0');
if (b < 38)
return (char)((int)b - 12 + (int)'A');
return (char)((int)b - 38 + (int)'a');
}
/// <summary>
/// Coverts the specified encoded character into the corresponding bit representation.
/// </summary>
/// <param name="c">The encoded character to convert</param>
/// <returns>The bit representation of the character</returns>
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
static byte CharToSixBit(char c)
{
if (c == '!')
return 0;
if (c == '$')
return 1;
if (c <= '9')
return (byte)((int)c - (int)'0' + 2);
if (c <= 'Z')
return (byte)((int)c - (int)'A' + 12);
return (byte)((int)c - (int)'a' + 38);
}
您可以将false传递给升序参数以确保编码值将按相反方向排序。我选择了!和$来完成Base64集合,因为它们对RowKey值有效。这个算法可以很容易地修改以支持额外的字符,但我坚信,对于RowKey值来说,较大的数字是没有意义的,因为表格存储键必须被有效地分割。以下是一些输出示例:
0 - > !!!! ASC & ZZZZ降序
1000 - > !!直流ASC & zzkL降序
2000 - > !! TE ASC & zzUj降序
3000 - > !!是ASC & zzF5降序
4000 - >!宇ASC & ZZ $ T递减
5000 - > $ C6 ASC & zylr递减
6000 - > $ RK ASC & zyWD递减
7000! - > $ HM ASC & zyGb递减
8000 - > $ X! ASC & zy0z递减
9000 - > 0AC ASC & zxnL递减
后您的代码,节省重新发明轮子 – 2011-05-03 02:09:24