mirror of
https://github.com/minescope/mineping.git
synced 2025-02-26 00:23:28 +03:00
perf: optimize varint decoding
docs: update type definitions
This commit is contained in:
parent
0b5c5e2938
commit
c71236f223
@ -66,65 +66,57 @@ const varint = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes a varint integer value from a byte buffer.
|
* Decodes a varint integer value from a buffer.
|
||||||
* @param {Buffer} buffer - The byte buffer to decode from.
|
* @param {Buffer} buffer - The byte buffer to decode from.
|
||||||
* @param {number} offset - The offset in the buffer to start decoding from.
|
* @param {number} offset - The offset in the buffer to start decoding from.
|
||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
decodeInt: (buffer, offset) => {
|
decodeInt: (buffer, offset) => {
|
||||||
let val = 0;
|
// Fast path for single-byte varints
|
||||||
let count = 0;
|
const firstByte = buffer.readUInt8(offset);
|
||||||
|
if (firstByte < 0x80) {
|
||||||
while (true) {
|
return firstByte;
|
||||||
const byte = buffer.readUInt8(offset++);
|
|
||||||
|
|
||||||
val |= (byte & 0x7f) << (count++ * 7);
|
|
||||||
|
|
||||||
if ((byte & 0x80) !== 0x80) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let val = firstByte & 0x7f;
|
||||||
|
let position = 7;
|
||||||
|
|
||||||
|
while (position < 32) {
|
||||||
|
const byte = buffer.readUInt8(++offset);
|
||||||
|
val |= (byte & 0x7f) << position;
|
||||||
|
|
||||||
|
if ((byte & 0x80) === 0) {
|
||||||
return val;
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
position += 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("VarInt is too big");
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the number of bytes required to decode a varint integer value.
|
* Calculates how many bytes are needed to encode a number as a VarInt
|
||||||
* @param {number} val - The varint integer value.
|
* VarInts use a variable number of bytes to efficiently encode integers
|
||||||
* @returns {5 | 7 | 8 | 1 | 2 | 3 | 4 | 6 | 9 | 10}
|
* Each byte uses 7 bits for the value and 1 bit to indicate if more bytes follow
|
||||||
|
* VarInts are never longer than 5 bytes
|
||||||
|
*
|
||||||
|
* @param {number} val - The number to calculate the VarInt length for
|
||||||
|
* @returns {1|2|3|4|5} The number of bytes needed to encode the value
|
||||||
*/
|
*/
|
||||||
decodeLength: (val) => {
|
decodeLength: (val) => {
|
||||||
// Constants representing the powers of 2 used for comparison
|
// Using bit shifts to calculate power of 2 thresholds
|
||||||
const N1 = Math.pow(2, 7);
|
// 1 << 7 = 2^7 = 128 - Numbers below this fit in 1 byte
|
||||||
const N2 = Math.pow(2, 14);
|
// 1 << 14 = 2^14 = 16,384 - Numbers below this fit in 2 bytes
|
||||||
const N3 = Math.pow(2, 21);
|
// 1 << 21 = 2^21 = 2,097,152 - Numbers below this fit in 3 bytes
|
||||||
const N4 = Math.pow(2, 28);
|
// 1 << 28 = 2^28 = 268,435,456 - Numbers below this fit in 4 bytes
|
||||||
const N5 = Math.pow(2, 35);
|
// Any larger number needs 5 bytes (maximum VarInt size)
|
||||||
const N6 = Math.pow(2, 42);
|
|
||||||
const N7 = Math.pow(2, 49);
|
|
||||||
const N8 = Math.pow(2, 56);
|
|
||||||
const N9 = Math.pow(2, 63);
|
|
||||||
|
|
||||||
// Return the number of bytes required based on the value
|
if (val < 1 << 7) return 1;
|
||||||
return val < N1
|
if (val < 1 << 14) return 2;
|
||||||
? 1
|
if (val < 1 << 21) return 3;
|
||||||
: val < N2
|
if (val < 1 << 28) return 4;
|
||||||
? 2
|
return 5;
|
||||||
: val < N3
|
|
||||||
? 3
|
|
||||||
: val < N4
|
|
||||||
? 4
|
|
||||||
: val < N5
|
|
||||||
? 5
|
|
||||||
: val < N6
|
|
||||||
? 6
|
|
||||||
: val < N7
|
|
||||||
? 7
|
|
||||||
: val < N8
|
|
||||||
? 8
|
|
||||||
: val < N9
|
|
||||||
? 9
|
|
||||||
: 10;
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
38
types/lib/varint.d.ts
vendored
38
types/lib/varint.d.ts
vendored
@ -1,10 +1,44 @@
|
|||||||
export default varint;
|
export default varint;
|
||||||
declare namespace varint {
|
declare namespace varint {
|
||||||
|
/**
|
||||||
|
* Encodes an integer value into a varint byte buffer.
|
||||||
|
* @param val - The integer value to encode.
|
||||||
|
*/
|
||||||
function encodeInt(val: number): Buffer;
|
function encodeInt(val: number): Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes a string value into a UTF-8 byte buffer.
|
||||||
|
* @param val - The string value to encode.
|
||||||
|
*/
|
||||||
function encodeString(val: string): Buffer;
|
function encodeString(val: string): Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes an unsigned short value into a byte buffer.
|
||||||
|
* @param val - The unsigned short value to encode.
|
||||||
|
*/
|
||||||
function encodeUShort(val: number): Buffer;
|
function encodeUShort(val: number): Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concatenates multiple byte buffers into a single byte buffer.
|
||||||
|
* @param chunks - An array of byte buffers to concatenate.
|
||||||
|
*/
|
||||||
function concat(chunks: Buffer[]): Buffer;
|
function concat(chunks: Buffer[]): Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes a varint integer value from a buffer.
|
||||||
|
* @param buffer - The byte buffer to decode from.
|
||||||
|
* @param offset - The offset in the buffer to start decoding from.
|
||||||
|
*/
|
||||||
function decodeInt(buffer: Buffer, offset: number): number;
|
function decodeInt(buffer: Buffer, offset: number): number;
|
||||||
function decodeString(val: Buffer, offset?: number): string;
|
|
||||||
function decodeLength(val: number): 5 | 7 | 8 | 1 | 2 | 3 | 4 | 6 | 9 | 10;
|
/**
|
||||||
|
* Calculates how many bytes are needed to encode a number as a VarInt.
|
||||||
|
* VarInts use a variable number of bytes to efficiently encode integers.
|
||||||
|
* Each byte uses 7 bits for the value and 1 bit to indicate if more bytes follow.
|
||||||
|
* VarInts are never longer than 5 bytes.
|
||||||
|
*
|
||||||
|
* @param val - The number to calculate the VarInt length for.
|
||||||
|
* @returns The number of bytes needed to encode the value (1-5).
|
||||||
|
*/
|
||||||
|
function decodeLength(val: number): 1 | 2 | 3 | 4 | 5;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user