ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Apache Cassandra 的字节可比编码(ByteComparable/ByteSource)深入解析

Apache Cassandra 的字节可比编码(ByteComparable/ByteSource)深入解析 数据库分布式数据库后端【免费下载链接】cassandraMirror of Apache Cassandra项目地址https://gitcode.com/gh_mirrors/cassandr/cassandra点击查看免费下载ByteComparable/ByteSource 是 Apache Cassandra 在 5.0 中引入的一套“字节可比byte-comparable”编码机制它把各类主键、聚类键、Token、UUID、浮点数乃至BigDecimal全部单向映射为可按无符号字典序直接比较的字节流从而让比较、排序、索引与合并可以在流式读取过程中尽早完成而不必把完整对象加载进内存。本文以仓库中的设计文档 ByteComparable.md 为主线结合 ByteSource.java、ByteComparable.java 等实现源码逐一说明编码动机、接口设计、各类数据类型的编码方案与示例并给出源码级的验证路径帮助你完整掌握这套机制的设计细节与工程落地。一、动机Cassandra 对比较机制的“重度依赖”与痛点Cassandra 的数据读写路径、协调coordination、压缩compaction、结果合并等环节高度依赖比较操作——只有通过对键进行排序与合并才能完成分区内有序扫描、多副本结果归并、SSTable 压缩等工作。与此同时Cassandra 支持的类型很多其中不少类型如整数、UUID、浮点数**天然不具备“字节序即比较序”**的性质即直接按无符号字节字典序比较原始编码并不能得到类型定义的比较结果。因此过去相当一部分比较操作不得不要求被比较对象完整加载到内存带来了三方面的代价时间开销加载、比较、之后又交给 GC 回收整个过程耗时空间开销磁盘索引需要保存完整键内存数据结构需要保存完整反序列化对象结构限制只能使用基于比较comparison-based的结构难以利用 Trie 这类更高效的数据结构。设计文档给出了明确的结论Cassandra 无法回避比较与排序但只要给对象加上“字节有序”这一简单结构比较机制就可以做得更聪明。文档中“byte order”特指按字节内容的无符号值做字典序比较。部分类型字符串、blob原本就具备该性质而最常用的整数、UUID 等并不具备。当字节序对所有键类型普遍可用后可以兑现四个关键收益比较只需一个简单方法核心机制无需感知任何具体类型前缀差异即可决定顺序可以用唯一前缀替代完整键参与排序可以用Trie存储、查询和迭代键区间获得快速查找与前缀压缩合并可通过合并 Trie完成大幅减少必要比较的次数。二、核心接口设计ByteSource 与 ByteComparable2.1 ByteSource未知长度的字节流字节序最大的优势之一是**“不必读完整段序列即可早做比较”因此设计文档规定字节有序的解释被表示为长度未知的字节流**由接口ByteSource承载。该接口只声明一个方法/** Consume the next byte, unsigned. Must be between 0 and 255, or END_OF_STREAM if there are no more bytes. */ int next();见 ByteSource.javanext()产出流中的下一个字节无符号 0~255流耗尽时返回ByteSource.END_OF_STREAMEND_OF_STREAM被选定为-1即(int) -1落在合法字节值 0~255 之外从而把“比较两个字节源”简化为对两个int的普通整数比较尽可能快。2.2 ByteComparable可请求字节序表示的实体ByteComparable是“其字节序解释可被请求”的实体接口public interface ByteComparable { ByteSource asComparableBytes(Version version); enum Version { LEGACY, // 旧版 sstable 格式使用的编码仅支持正向值→字节可比转换 OSS50, // Cassandra 5.0 编码 } ByteComparable EMPTY (Version version) - ByteSource.EMPTY; ... }见 ByteComparable.java关键点asComparableBytes(Version)返回该值的字节可比表示Version枚举区分两套编码LEGACY旧版 sstable 格式只做正向转换与OSS50Cassandra 5.0 编码双向转换。文档正文聚焦于双向的OSS50版本接口由DecoratedKey实现见 DecoratedKey.javapublic abstract class DecoratedKey implements PartitionPosition, FilterKey其ByteComparable能力用于分区键的 Trie 索引聚类键及边界通过ClusteringComparator.asByteComparable请求见 ClusteringComparator.java其 javadoc 明确承诺compare(x, y) compareLexicographicallyUnsigned(asByteComparable(x), asByteComparable(y))且asByteComparable(x)不是asByteComparable(y)的前缀逆向转换由Buffer/NativeDecoratedKey.fromByteComparable与ClusteringComparator.clustering/bound/boundaryFromByteComparable提供流式逆向工具集中在 ByteSourceInverse.java例如getSignedFixedLength、getSignedFixedLengthFloat分别还原“符号位取反的定长整数”和“按 IEEE-754 规则翻转的浮点数”。2.3 为什么要把复杂类型“拍平”成单字节序列为了把类型信息完全从存储机制中抽象掉文档规定复杂类型也要压扁flatten为单一字节序列。做法是在前部、组件之间、末尾插入分隔字节并对变长序列做编码。分隔符与终结符的具体取值见 ByteSource.java常量值含义MIN_SEPARATOR/MAX_SEPARATOR0x10/0xEF所有分隔符必须落在该区间NEXT_COMPONENT0x40下一组件标记NEXT_COMPONENT_EMPTY0x3F空值组件标记如Int32Type的空 buffer 表示 nullNEXT_COMPONENT_EMPTY_REVERSED0x41反转类型下的空值标记NEXT_COMPONENT_NULL0x3E元组、map、set、聚类键中的 null 组件标记TERMINATOR0x38序列默认终结符LT_NEXT_COMPONENT0x20排他/包含下界结束符小于任何更多组件GT_NEXT_COMPONENT0x60排他/包含上界结束符大于任何更多组件2.4 接口层提供的实用工具ByteComparable与ByteSource还提供了若干实用工厂与工具方法ByteComparable.of(String/long/int)、fixedLength(...)用于测试的简单工厂ByteComparable.separatorPrefix(prevMax, currMin)/separatorGt(...)在两个字节源之间构造分隔值严格大于prevMax且不大于currMin对应 ByteSource.Separator 的实现——返回两个流公共前缀之后“多一个字节”的流ByteComparable.cut(src, cutoff)截断到指定长度ByteComparable.length(src, version)返回不含终结符的字节可比长度ByteComparable.compare(bytes1, bytes2, version)按字节可比表示的字典序比较用于测试ByteComparable.diffPoint(...)返回两个表示产生差异的最小前缀长度ByteSource.withTerminator(terminator, srcs...)/Multi把多个子源组合成带分隔与终结符的序列见 ByteSource.javaMulti在每组件前输出NEXT_COMPONENT遇 null 子源输出NEXT_COMPONENT_NULLByteSource.cutOrRightPad(src, cutoff, padding)定长化——不足则右补超出则截断ByteSource.peekable(src)带peek()的包装便于不消费字节地预读。三、编码设计的两组核心性质文档用四条形式化性质刻画编码要求。为便于阅读以下用文字重述比较等价 (1)对任意 x、ycompareBytesUnsigned(byteOrdered(x), byteOrdered(y)) compare(x, y)。这是最基本、最必要的要求前缀自由 (2)对任意 x≠ybyteOrdered(x)不是byteOrdered(y)的前缀。它允许构造“多值序列”的编码并为数据结构带来额外效率弱化版比较等价 (3)允许在byteOrdered(x)之后追加分隔字节 b₁、b₂b ∈ [0x10–0xEF]仍保证无符号字节比较方向与类型比较一致弱前缀自由 (4)byteOrdered(x)b不是byteOrdered(y)的前缀。(3) 是 (1) 的加强版且当 (2) 成立时必然成立(4) 可由 (2) 平凡推出。引入这两个弱化版本的原因在于每个值之后要追加一个分隔字节而追加后仍须满足原始要求——这正是 (3)、(4) 的用武之地。上述约定也被写进类型层契约AbstractType见 AbstractType.java与Token见 Token.java的 javadoc 都注明同一组比较等价与弱前缀自由保证。四、各数据类型的字节可比编码方案以下各小节逐类给出设计文档中的完整编码规则与示例示例表中的字节均为十六进制。4.1 定长无符号整数Murmur Token、日期时间最简单的情形直接使用大端big-endian原始字节即可。无符号定长值的比较结果天然一致且定长值平凡地满足前缀自由因此 (1)(2) 成立(3)(4) 随之成立。4.2 定长有符号整数byte、short、int、旧版 bigint与上面相同但需要翻转符号位使负数排在正数之前。翻转后MIN_VALUE→0x00…-1→0x7F…0→0x80…MAX_VALUE→0xFF…按无符号整数比较翻转后的结果与按有符号比较原数等价。源码实现见 ByteSource.SignedFixedLengthNumber仅对第一个字节执行v ^ 0x80其余字节原样输出逆向见 ByteSourceInverse.getSignedFixedLength同样是仅翻转首字节符号位。类型与值原始字节编码后int 100 00 00 0180 00 00 01short -1FF FF7F FFbyte 00080byte -2FE7Eint MAX_VALUE7F FF FF FFFF FF FF FFlong MIN_VALUE80 00 00 00 00 00 00 0000 00 00 00 00 00 00 004.3 变长整数编码当前 bigint 采用当较小数值常见时可采用类似 UTF-8 的变长编码以显著节省空间同时仍能高效编码大数。无符号数开头用尽可能多的 MSB 置 1表示额外字节数随后跟一个 0 与数值位0~127 编码为 1 字节每增加 1 字节多容纳 7 位8 字节全用满时无需第 9 个 0 位因此可编到 9 字节较长的数 MSB 的 1 更多因而比较更大且永远使用最短表示长度由首字节初始位决定故任何值都不会是另一个的前缀。值原始 8 字节编码后000 00 00 00 00 00 00 0000100 00 00 00 00 00 00 0101127 (2⁷-1)00 00 00 00 00 00 00 7F7F128 (2⁷)00 00 00 00 00 00 00 8080 8016383 (2¹⁴-1)00 00 00 00 00 00 3F FFBF FF16384 (2¹⁴)00 00 00 00 00 00 40 00C0 40 002³¹-100 00 00 00 7F FF FF FFF0 7F FF FF FF2³¹00 00 00 00 80 00 00 00F0 80 00 00 002⁵⁶-100 FF FF FF FF FF FF FFFE FF FF FF FF FF FF FF2⁵⁶01 00 00 00 00 00 00 00FF 01 00 00 00 00 00 00 002⁶⁴-1FF FF FF FF FF FF FF FFFF FF FF FF FF FF FF FF FF有符号数必须以符号位开头且要保证“更长的负数”比“更短的负数”更小。编码规则首比特为反转后的符号正为 1、负为 0随后是与反转符号一致的长度比特序列再跟一个不同比特9 字节编码无需此位最后是数值的二进制补码。值原始 8 字节编码后100 00 00 00 00 00 00 0181-1FF FF FF FF FF FF FF FF7F000 00 00 00 00 00 00 00806300 00 00 00 00 00 00 3FBF-64FF FF FF FF FF FF FF C0406400 00 00 00 00 00 00 40C0 40-65FF FF FF FF FF FF FF BF3F BF819100 00 00 00 00 00 1F FFDF FF819200 00 00 00 00 00 20 00E0 20 00Integer.MAX_VALUE00 00 00 00 7F FF FF FFF8 7F FF FF FFLong.MIN_VALUE80 00 00 00 00 00 00 0000 00 00 00 00 00 00 00 00源码实现见 ByteSource.VariableLengthUnsignedInteger按63 - numberOfLeadingZeros(value | 1)推导比特数、以 7 位为一组切分与 ByteSource.VariableLengthInteger先value ^ negativeMask做符号处理9 字节情形直接输出0x00/0xFF首字节。4.4 定长浮点数float、doubleIEEE-754 在设计时就考虑了字节级比较提供关键保证若 x、y 符号相同则bytes(x) ≥ bytes(y) ⇔ |x| ≥ |y|。因此只需两步翻转符号位让负数小于正数若为负数再翻转其余所有位使绝对值更大的数成为更小的整数。这正好与Double.compare的行为一致Double.compare为了在浮点数上定义自然序并不完全等同于数值比较。类型与值原始字节编码后float 1.03F 80 00 00BF 80 00 00float 0.000 00 00 0080 00 00 00float -0.080 00 00 007F FF FF FFfloat -1.0BF 80 00 0040 7F FF FFdouble 1.03F F0 00 00 00 00 00 00BF F0 00 00 00 00 00 00double Inf7F F0 00 00 00 00 00 00FF F0 00 00 00 00 00 00double -InfFF F0 00 00 00 00 00 0000 0F FF FF FF FF FF FFdouble NaN7F F8 00 00 00 00 00 00FF F8 00 00 00 00 00 00源码实现见 ByteSource.SignedFixedLengthFloat首字节若v 0x80判定为负并置invert然后对后续字节整体v ^ 0xFF逆向逻辑见 ByteSourceInverse.getSignedFixedLengthFloat。4.5 UUIDUUID 本质是定长无符号整数但比较时先比较版本/类型位且时间 UUID 需要重排比特位。字节可比编码的做法是重排字节先把版本数字提出来再输出其余数字若版本为 1时间 UUID其余部分使用时间特殊顺序。类型与值原始字节编码后Random (v4)cc520882-9507-44fb-8fc9-b349ecdee6584cc52088295074fb8fc9b349ecdee658Time (v1)2a92d750-d8dc-11e6-a2de-cf8ecd4cf05311e6d8dc2a92d750a2decf8ecd4cf0534.6 多组件序列分区/聚类键、元组、边界与 null如前所述序列编码在前部、组件之间、末尾分别加入分隔字节与终结符取值0x40与0x38。它们服务三个目的支持部分指定边界严格/排他与非严格/包含语义用比分隔符、终结符更小/更大的终结值结束一个边界——0x20表示/≥0x60表示≤/支持 null 与 empty 编码null 用分隔符0x3E、empty 用0x3F后接无值字节总是小于该组件有非空值的序列但不小于在该组件处结束的序列帮助识别变长组件的结束见下一节。示例表格中·仅为可视化边界分隔实际编码中不存在类型与值原始字节编码后(short 1, float 1.0)00 01, 3F 80 00 0040·80 01·40·BF 80 00 00·38(short -1, null)FF FF, —40·7F FF·3E·38≥ (short 0, float -Inf)00 00, FF 80 00 00, 40·80 00·40·00 7F FF FF·20 (short MIN)80 00, 40·00 00·20 (null)3E·60BOTTOM20TOP60因为所有分隔符落在0x10–0xEF内部组件使用同一分隔符null 用更小的分隔符序列组件数固定或在可更短时使用不同的尾部值——所以 (3)(4) 保证序列的字节比较方向与字典序比较方向一致结合第三点(4) 也保证任何编码都不是另一个的前缀。这意味着数据库中使用的所有分区键与聚类键编码都是前缀自由的。4.7 变长字节可比数据ASCII、UTF-8 字符串、blob、InetAddress单独比较时这些数据可直接比较无需重解释但放进拍平的序列后必须明确定义值之间的边界且保持顺序。为此引入“值结束标记”由于较短的值必须较小该标记取0并需要对输入中真正的0做转义escape。规则如下若输入不以00结尾则在末尾追加一个00输入中出现00字节编码为00 FF输入中出现连续的n个00编码为00FE×(n-1) FF避免 00 大段数据体积翻倍若输入以00结尾则把最后的FF改为FE保证它小于“同样内容再追加 00”的值。原始字节/序列编码后22 0022 00 FE22 00 00 3322 00 FE FF 33 0022 00 1122 00 FF 11 00(blob 22, short 0)40·22 00·40·80 00·40≥ (blob 22 00)40·22 00 FE·20≤ (blob 22 00 00)40·22 00 FE FE·60编码内00之后只可能跟FE或FF因此若某编码是另一编码的前缀后者下一字节必为FE/FF这保证了 (4)前者追加10–EF后不再成为后者前缀与 (3)。源码实现对应 ByteSource.AbstractEscaper其 javadoc 给出示例A\0\0B→4100FEFF4200、AB→414200常量定义见 ByteSource.javaESCAPE0x00、ESCAPED_0_CONT0xFE、ESCAPED_0_DONE0xFF。4.8 变长整数 varint含 RandomPartitioner Token——旧版编码若无界整数保证以非零数字开头比较时先比较有符号长度表示更长的数绝对值更大仅当长度相等时才需要比较已知长度的数字序列这里“数字”指 base-256 的字节。编码步骤去掉前导零负数时BigInteger以0xFF表示前导 0若长度 ≥ 128正数以0xFF、负数以0x00打头每 128 补一个直到剩余不足 128用一字节编码符号与剩余长度正数0x80 (length - 1)绝对值越大越高负数0x7F - (length - 1)绝对值越大越低且所有负数低于所有正数粘贴数值字节负数以二进制补码编码。比较两个数时要么长度前缀不同要么长度相同才比较内容字节因此长数不会与“短数组合成多组件序列”混淆——任何值都不是另一个的前缀(1)(2) 成立进而 (3)(4) 成立。值原始字节编码后00080·0010180·01-1FF7F·FF25500 FF80·FF-256FF 007F·0025601 0081·01 002¹⁶01 00 0082·01 00 00-2³²FF 00 00 00 007C·00 00 00 002¹⁰²⁴01 00(128 个)FF 80·01 00(128 个)-2²⁰⁴⁸FF 00(256 个)00 00 80·00(256 个)4.9 变长整数 varint——当前编码由于变长整数也常用于存储较小范围的整数当前 varint 方案在旧版基础上叠加了 4.3 节的变长编码去掉前导零6 字节及以内直接映射为变长整数编码更长编码为符号字节负为00、正为FF与上述变长编码首字节可区分字节数减 7 后再变长编码负数取反使长度更大者比较更小数值字节二进制补码。绝不在“变长编码已够用”时使用更长编码。符号字节不可能与变长编码首字节混淆因此任何值都不是另一个的前缀符号字节使负数反之为正数小于任何变长编码整数因而一个用变长、另一个用扩展编码时顺序依然正确更长负数因长度字节取反而更小更长正数更大。值原始字节编码后0008010181-1FF7F25500 FFC0 FF-256FF 003F 0025601 00C1 002¹⁶01 00 00E1 00 00-2³²FF 00 00 00 0007 00 00 00 002⁵⁶-100 FF FF FF FF FF FF FFFE FF FF FF FF FF FF FF-2⁵⁶FF 00 00 00 00 00 00 0001 00 00 00 00 00 00 002⁵⁶01 00 00 00 00 00 00 00FF·00·01 00 00 00 00 00 00 00-2⁵⁶-1FE FF FF FF FF FF FF FF00·FF·FE FF FF FF FF FF FF FF2¹⁰²⁴01 00(128 个)FF·7A·01 00(128 个)-2²⁰⁴⁸FF 00(256 个)00·7F 06·00(256 个)4.10 变长浮点小数 decimal变长浮点数更复杂但可按 IEEE-754 的思路处理归一化为符号、尾数、带符号指数使尾数成为带非零首位的 1 数随后依次比较符号、指数、尾数符号为负时指数与尾数的比较含义相反即可得到小数序。两个额外难点不能用二进制/base-256 精确编码0.1这类小数必须用十进制基为利用字节效率采用base-100浮点编码与前述比较思路在任何数基下都成立BigDecimal混用多种基整数部分是二进制编码scale 是十的幂。因此不能直接转换其字节必须先实例化BigDecimal再用其方法按数值运算。编码规则数值为 0编码为单个0x80转成 base-100 的带符号尾数与带符号指数若数值为负指数符号取反形成“调制指数modulated exponent”输出一个字节符号以0x80正/0x00负编码指数长度去前导 0以0x40 modulated_exponent_length编码长度带调制指数符号输出exponent_length个调制指数字节二进制补码保证负值正确排序输出0x80 尾数首带符号字节尾数乘 100 后向 -∞ 取整余数保持为正从而每个新字节都为其增加值短序列值更低更新尾数为上述取整后的余数保证 ≥ 0尾数非零时循环输出0x80 首字节并更新余数输出0x00结尾。为什么顺序正确首差异字节的讨论首字节差异可能来自数值符号或零负数起于0x3c–0x44零为0x80正数起于0xbc–0xc4指数符号与数值符号的调制正数负指数更小、负数相反调制保证正确序调制指数长度长度符号由指数与数值符号合成两种情况下均给出正确序调制指数字节差异此时长度与符号相同字节更小 ⇒ 调制指数更小 ⇒ 正数指数更小、负数指数绝对值更大均使数值更小不可能把一个数的指数与另一个数的尾数混在一起比较二者首字节区间不同尾数字节差异指数相等时字节更小 ⇒ 带符号尾数更小 ⇒ 数值更小一个尾数先结束短者视为更小因为尾部字节是00所有尾数至少一个字节故首尾数字节不可能触发该情形其余字节非负且至少一个非零其尾数更大、数值更大。值mexp尾数尾数字节编码后1.110.0110. 01 10C1·01·81 8A·00110.01. 01C1·01·81·000.0100.01. 01C0·81·00080-0.010-0.01. -0140·81·00-1-1-0.01. -013F·FF·7F·00-1.1-1-0.0110. -02 903F·FF·7E DA·00-98.9-1-0.9890. -99 103F·FF·1D 8A·00-99-1-0.99. -993F·FF·1D·00-99.9-1-0.9990.-100 103F·FF·1C 8A·00-8.1e2000-1001-0.0810. -09 903E·FC 17·77 DA·00-8.1e-2000999-0.0810. -09 9042·03 E7·77 DA·008.1e-2000-9990.0810. 08 10BE·FC 19·88 8A·008.1e200010010.0810. 08 10C2·03 E9·88 8A·00mexp 为“调制指数”即 指数 × 符号这些值前缀自由任何指数的编码都不是另一个的前缀且尾数除最后字节外不可能出现00故 (1)–(4) 全部满足。五、null 与 empty 的区分Cassandra 部分类型如数值允许 null 值以空字节 buffer表示这与 null 字节 buffer 是两回事后者在某些场景也会出现。文档给出关键区分聚类列中的 null 值类型允许时被解释为空字节 buffer用空分隔符0x3F编码未指定的聚类列位于聚类规格末尾COMPACT STORAGE或二级索引场景可能出现使用 null 分隔符0x3E。这两个常量在 ByteSource.java 中分别命名为NEXT_COMPONENT_EMPTY与NEXT_COMPONENT_NULL。六、Reversed反转类型反转类型的做法很直接把编码字节序列的所有位翻转bitwise not。由于源类型编码满足 (3)(4)翻转后对反转比较器同样满足源类型满足 (1)(2) 时反转后亦然。唯一的例外修正出现在序列中反转类型的 empty 编码必须大于所有值因此不再用0x3F改用0x41即 ByteSource.java 的NEXT_COMPONENT_EMPTY_REVERSED。null 编码不修改——即使在反转类型中null 依然比较更小。七、源码级的应用与验证路径7.1 在核心数据结构中的应用TrieMemtable以BYTE_COMPARABLE_VERSION ByteComparable.Version.OSS50运行见 TrieMemtable.java这正是文档“Tries 可存储、查询、迭代键区间”收益的直接落地内存/磁盘 TrieInMemoryReadTrie.get(ByteComparable path)见 InMemoryReadTrie.java与InMemoryTrie.putSingleton(ByteComparable key, ...)见 InMemoryTrie.java都以ByteComparable为路径/键类型CollectionMergeTrie见 CollectionMergeTrie.java则实现了“合并 Trie 完成合并”的思路类型层契约AbstractTypeAbstractType.java与TokenToken.java的 javadoc 直接引用文档中的比较等价与弱前缀自由性质各AbstractType子类即各映射的实际实现位置空键编码特例PartitionerDefinedOrder对 OSS50 及以上版本把空键编码为 null 字节源见 PartitionerDefinedOrder.java。7.2 单元测试仓库在 test/unit/org/apache/cassandra/utils/bytecomparable/ 下提供了成体系的验证ByteSourceConversionTest值 → 字节可比的转换正确性ByteSourceInverseTest逆向转换字节可比 → 值正确性ByteSourceComparisonTest字节可比表示之间的比较与类型比较一致性ByteSourceSequenceTest多组件序列分隔符、终结符、null/empty、边界的组合编码AbstractTypeByteSourceTest各AbstractType子类编码的覆盖测试。这些测试直接对应文档中的性质 (1)–(4) 与各节编码规则是理解与验证该机制最直接的入口。八、小结ByteComparable/ByteSource 为 Cassandra 5.0 提供了一套统一、流式、前缀自由弱前缀自由的字节可比编码以单方法next()的ByteSource承载“未知长度的字节流”END_OF_STREAM -1使比较退化为整数比较对定长/变长整数、IEEE-754 浮点、UUID、字符串/blob、BigDecimal、多组件序列、null/empty、反转类型分别设计了保持顺序且弱前缀自由的编码在工程上支撑了 TrieMemtable、内存/磁盘 Trie、AbstractType/Token的编码契约并有完整的转换、逆转换、比较与序列测试守护正确性。这套机制把“比较与排序”从类型耦合的逐对象加载转变为类型无关的流式字节比较是 Cassandra 在存储与索引层继续优化的关键基础设施之一。若需深入可直接阅读设计文档 ByteComparable.md、接口实现 ByteSource.java、ByteComparable.java 与逆向工具 ByteSourceInverse.java。赞分享数据库分布式数据库后端【免费下载链接】cassandraMirror of Apache Cassandra项目地址https://gitcode.com/gh_mirrors/cassandr/cassandra点击查看免费下载相关推荐Cassandra 字节序翻译机制ByteComparable/ByteSource深度解析类型到字节序的编码原理与实现Cassandra 字节序翻译机制ByteComparable/ByteSource深度解析类型到字节序的编码原理与实现 导读 本文基于 Apache C数据库分布式数据库大数据后端QuickJS字节码解析深入理解qjsc编译器工作原理QuickJS字节码解析深入理解qjsc编译器工作原理 QuickJS是一个轻量级且高效的JavaScript引擎其编译器qjsc能够将JavaScript语言运行时解释器编程语言Perfetto ProtoVM Compiler 深入解析从 CompileConfig 到 VmProgram 字节码的编译流水线Perfetto ProtoVM Compiler 深入解析从 CompileConfig 到 VmProgram 字节码的编译流水线 ProtoVM 是 P可观测性后端开发工具前端数据可视化上一篇AMD Ryzen处理器调试完全指南SMU Debug Tool让你的电脑性能飙升下一篇深度掌控AMD Ryzen硬件参数SMU Debug Tool完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表