"가변 정수 인코딩"을 말합니다. 여기서 직렬화 될 때 정수를 저장하는 데 사용되는 비트 수는 4 바이트로 고정되지 않습니다. varint in the protocol buffer documentation에 대한 설명이 있습니다.
Google's protocol buffers 인코딩에 사용되며 protocol buffer source code을 검색 할 수 있습니다.
CodedOutputStream
정확한 인코딩 기능 WriteVarint32FallbackToArrayInline 포함에만 target
배열의 마지막에 추가 바이트를 추가합니다
inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
uint32 value, uint8* target) {
target[0] = static_cast<uint8>(value | 0x80);
if (value >= (1 << 7)) {
target[1] = static_cast<uint8>((value >> 7) | 0x80);
if (value >= (1 << 14)) {
target[2] = static_cast<uint8>((value >> 14) | 0x80);
if (value >= (1 << 21)) {
target[3] = static_cast<uint8>((value >> 21) | 0x80);
if (value >= (1 << 28)) {
target[4] = static_cast<uint8>(value >> 28);
return target + 5;
} else {
target[3] &= 0x7F;
return target + 4;
}
} else {
target[2] &= 0x7F;
return target + 3;
}
} else {
target[1] &= 0x7F;
return target + 2;
}
} else {
target[0] &= 0x7F;
return target + 1;
}
}
계단식 if
들 경우 value
보증 그 여분의 바이트 크기. 0x80
은 기록중인 바이트를 마스크하고 value
은 아래로 이동합니다. 내가 알 수있는 바로는 0x7f
마스크는 "인코딩의 마지막 바이트"를 나타냅니다. (OR'ing 0x80
, 가장 높은 비트는 항상 1
이고, 마지막 바이트는 가장 높은 비트를 지 웁니다 (0x7f
의 AND로). 따라서 varints를 읽을 때 가장 높은 비트에 0이 포함 된 바이트가 나타날 때까지 읽습니다 .
난 그냥 당신이. 기본 개념이 유사한 것으로 보인다. 불행하게도, 그것은 하지의 구체적. 죄송합니다, 그 코드는 기본 VarInt 인코딩 (여전히보다 빠른 7 비트)에 대해이었다 "인코딩 그룹 VarInt"에 대해 질문 실현 프로토콜 버퍼에 64 비트 숫자를 저장하는 데 사용되는 코드입니다. 코드가 오픈 소스로되어 있다면 놀랄 일이 아닙니다.
varint
의 아이디어와 "Group varint "를 사용하면 슬라이드를 직접 요리 할 수 없습니다.
다음은 디코딩 코드가 포함 된 Group VarInt compression을 설명하는 또 다른 페이지입니다. 불행히도 공개적으로 사용 가능한 구현을 암시하지만 참조를 제공하지는 않습니다.
void DecodeGroupVarInt(const byte* compressed, int size, uint32_t* uncompressed) {
const uint32_t MASK[4] = { 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF };
const byte* limit = compressed + size;
uint32_t current_value = 0;
while (compressed != limit) {
const uint32_t selector = *compressed++;
const uint32_t selector1 = (selector & 3);
current_value += *((uint32_t*)(compressed)) & MASK[selector1];
*uncompressed++ = current_value;
compressed += selector1 + 1;
const uint32_t selector2 = ((selector >> 2) & 3);
current_value += *((uint32_t*)(compressed)) & MASK[selector2];
*uncompressed++ = current_value;
compressed += selector2 + 1;
const uint32_t selector3 = ((selector >> 4) & 3);
current_value += *((uint32_t*)(compressed)) & MASK[selector3];
*uncompressed++ = current_value;
compressed += selector3 + 1;
const uint32_t selector4 = (selector >> 6);
current_value += *((uint32_t*)(compressed)) & MASK[selector4];
*uncompressed++ = current_value;
compressed += selector4 + 1;
}
}
대단히 감사하고 당신의 업데이트를 기다리고있다. –
. 그건 그렇고, 프레 젠 테이션에서 좋은 발견, 나는 나중에 확인해 보겠습니다.:) – Stephen
당신은 빠르다. 나는 곧 그것을 점검 할 것이다. –