首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Booksleeve处理Int64值

用Booksleeve处理Int64值
EN

Stack Overflow用户
提问于 2013-07-11 18:08:15
回答 1查看 210关注 0票数 1

我有一个关于Marc Gravell的Booksleeve库的问题。

我试着理解booksleeve是如何处理Redis值的(实际上我在Int64中有十亿长的值)

我使用反射来理解设置的长值覆盖。

代码语言:javascript
复制
// BookSleeve.RedisMessage
protected static void WriteUnified(Stream stream, long value)
{
if (value >= 0L && value <= 99L)
{
    int i = (int)value;
    if (i <= 9)
    {
        stream.Write(RedisMessage.oneByteIntegerPrefix, 0, RedisMessage.oneByteIntegerPrefix.Length);
        stream.WriteByte((byte)(48 + i));
    }
    else
    {
        stream.Write(RedisMessage.twoByteIntegerPrefix, 0, RedisMessage.twoByteIntegerPrefix.Length);
        stream.WriteByte((byte)(48 + i / 10));
        stream.WriteByte((byte)(48 + i % 10));
    }
}
else
{
    byte[] bytes = Encoding.ASCII.GetBytes(value.ToString());
    stream.WriteByte(36);
    RedisMessage.WriteRaw(stream, (long)bytes.Length);
    stream.Write(bytes, 0, bytes.Length);
}

stream.Write(RedisMessage.Crlf, 0, 2);
}

我不明白为什么有超过两位数的int64,长码是用ascii编码的?

为什么不使用byte[]?我知道我可以使用byte[]重写来做到这一点,但我只想理解这个实现来优化我的实现。可能和Redis存储有关系。

提前谢谢你,Marc :)

附言:我仍然非常热衷于你的下一个主要版本,因为我可以使用长值键而不是字符串。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-11 19:13:36

它用ASCII码编写,因为这是的要求。

如果你仔细看,它总是编码为ASCII码-但对于最常见的情况(0-9,10-99),我对它进行了特殊处理,因为以下是非常简单的结果:

代码语言:javascript
复制
 x => $1\r\nX\r\n
xy => $2\r\nXY\r\n

其中xy是0-99范围内的数字的前两位,XY是偏移48 ('0')的数字(as数字)-因此十进制17变成字节序列(十六进制):

代码语言:javascript
复制
24-32-0D-0A-31-37-0D-0A

当然,这也可以通过按顺序写入每个数字,将数字值偏移48 ('0'),并处理负号来实现-我猜答案很简单,“因为我以简单但明显正确的方式编码”。考虑一下值-123 -它被编码为$4\r\n-123\r\n (嘿,不要看我-协议不是我设计的)。这有点笨拙,因为它需要先计算缓冲区长度,然后写入缓冲区长度,然后写入值-记住要按100s,10s,1s的顺序写入(这比反过来写要难得多)。

完全愿意重新审视它--简单地说:它是有效的。

当然,如果您有一个可用的临时缓冲区,那么它就变得微不足道了--您只需以简单的顺序编写它,然后反转临时缓冲区的一部分。我将检查是否有一个可用(如果没有,添加一个也不是不合理的)。

我还应该澄清的是:还有整数类型,它会将-123编码为:-123\r\n -然而,在内存中有很多地方这是不起作用的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17590625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档