Initial commit
This commit is contained in:
671
node_modules/@maplibre/mlt/dist/encoding/integerEncodingUtils.js
generated
vendored
Normal file
671
node_modules/@maplibre/mlt/dist/encoding/integerEncodingUtils.js
generated
vendored
Normal file
@@ -0,0 +1,671 @@
|
||||
import IntWrapper from "../decoding/intWrapper";
|
||||
import { createFastPforEncoderWorkspace, encodeFastPforInt32WithWorkspace } from "./fastPforEncoder";
|
||||
import { encodeBigEndianInt32s } from "./bigEndianEncode";
|
||||
export function encodeVarintInt32Value(value, dst, offset) {
|
||||
let v = value;
|
||||
while (v > 0x7f) {
|
||||
dst[offset.get()] = (v & 0x7f) | 0x80;
|
||||
offset.increment();
|
||||
v >>>= 7;
|
||||
}
|
||||
dst[offset.get()] = v & 0x7f;
|
||||
offset.increment();
|
||||
}
|
||||
export function encodeVarintInt32(values) {
|
||||
const buffer = new Uint8Array(values.length * 5);
|
||||
const offset = new IntWrapper(0);
|
||||
for (const value of values) {
|
||||
encodeVarintInt32Value(value, buffer, offset);
|
||||
}
|
||||
return buffer.slice(0, offset.get());
|
||||
}
|
||||
export function encodeVarintInt64(values) {
|
||||
const buffer = new Uint8Array(values.length * 10);
|
||||
const offset = new IntWrapper(0);
|
||||
for (const value of values) {
|
||||
encodeVarintInt64Value(value, buffer, offset);
|
||||
}
|
||||
return buffer.slice(0, offset.get());
|
||||
}
|
||||
function encodeVarintInt64Value(value, dst, offset) {
|
||||
let v = value;
|
||||
while (v > 0x7fn) {
|
||||
dst[offset.get()] = Number(v & 0x7fn) | 0x80;
|
||||
offset.increment();
|
||||
v >>= 7n;
|
||||
}
|
||||
dst[offset.get()] = Number(v & 0x7fn);
|
||||
offset.increment();
|
||||
}
|
||||
export function encodeVarintFloat64(values) {
|
||||
// 1. Calculate the exact size required for the buffer
|
||||
let size = 0;
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
let val = values[i];
|
||||
// Ensure we handle the value as a positive integer
|
||||
val = val < 0 ? 0 : Math.floor(val);
|
||||
// 0 always takes 1 byte
|
||||
if (val === 0) {
|
||||
size++;
|
||||
continue;
|
||||
}
|
||||
// Calculate bytes needed: ceil(log128(val + 1))
|
||||
while (val > 0) {
|
||||
size++;
|
||||
val = Math.floor(val / 128);
|
||||
}
|
||||
}
|
||||
const dst = new Uint8Array(size);
|
||||
const offset = new IntWrapper(0);
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
encodeVarintFloat64Value(values[i], dst, offset);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
/**
|
||||
* Encodes a single number into the buffer at the given offset using Varint encoding.
|
||||
* Handles numbers up to 2^53 (MAX_SAFE_INTEGER) correctly.
|
||||
*/
|
||||
function encodeVarintFloat64Value(val, buf, offset) {
|
||||
// Ensure integer
|
||||
val = Math.floor(val);
|
||||
// Handle 0 explicitly or ensure loop runs once
|
||||
if (val === 0) {
|
||||
buf[offset.get()] = 0;
|
||||
offset.increment();
|
||||
return;
|
||||
}
|
||||
while (val >= 128) {
|
||||
// Write 7 bits of data | 0x80 (continuation bit)
|
||||
buf[offset.get()] = (val % 128) | 0x80;
|
||||
offset.increment();
|
||||
// Shift right by 7 bits
|
||||
val = Math.floor(val / 128);
|
||||
}
|
||||
// Write the last byte (no continuation bit)
|
||||
buf[offset.get()] = val;
|
||||
offset.increment();
|
||||
}
|
||||
export function encodeFastPfor(values) {
|
||||
const encoderWorkspace = createFastPforEncoderWorkspace();
|
||||
const encodedWords = encodeFastPforInt32WithWorkspace(values, encoderWorkspace);
|
||||
return encodeBigEndianInt32s(encodedWords);
|
||||
}
|
||||
export function encodeZigZagInt32Value(value) {
|
||||
return (value << 1) ^ (value >> 31);
|
||||
}
|
||||
export function encodeZigZagInt64Value(value) {
|
||||
return (value << 1n) ^ (value >> 63n);
|
||||
}
|
||||
export function encodeZigZagFloat64Value(n) {
|
||||
return n >= 0 ? n * 2 : n * -2 - 1;
|
||||
}
|
||||
export function encodeZigZagInt32(data) {
|
||||
const result = new Uint32Array(data.length);
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
result[i] = encodeZigZagInt32Value(data[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
export function encodeZigZagInt64(data) {
|
||||
const result = new BigUint64Array(data.length);
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
result[i] = encodeZigZagInt64Value(data[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
export function encodeZigZagFloat64(data) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
data[i] = encodeZigZagFloat64Value(data[i]);
|
||||
}
|
||||
}
|
||||
export function encodeUnsignedRleInt32(input) {
|
||||
if (input.length === 0) {
|
||||
return { data: new Uint32Array(0), runs: 0 };
|
||||
}
|
||||
const runLengths = [];
|
||||
const runValues = [];
|
||||
let currentRunLength = 0;
|
||||
let currentValue = input[0];
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const nextValue = input[i];
|
||||
if (nextValue === currentValue) {
|
||||
currentRunLength++;
|
||||
}
|
||||
else {
|
||||
// End of the current run, record it
|
||||
runLengths.push(currentRunLength);
|
||||
runValues.push(currentValue);
|
||||
// Start a new run
|
||||
currentValue = nextValue;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
}
|
||||
// Record the final run after the loop finishes
|
||||
runLengths.push(currentRunLength);
|
||||
runValues.push(currentValue);
|
||||
// Combine lengths and values into the final structured output array
|
||||
const numRuns = runLengths.length;
|
||||
const encodedData = new Uint32Array(numRuns * 2);
|
||||
// Populate the first half with lengths
|
||||
encodedData.set(runLengths, 0);
|
||||
// Populate the second half with values, offset by the total number of runs
|
||||
encodedData.set(runValues, numRuns);
|
||||
return { data: encodedData, runs: numRuns };
|
||||
}
|
||||
export function encodeUnsignedRleInt64(input) {
|
||||
if (input.length === 0) {
|
||||
return { data: new BigUint64Array(0), runs: 0 };
|
||||
}
|
||||
const runLengths = [];
|
||||
const runValues = [];
|
||||
let currentRunLength = 0;
|
||||
let currentValue = input[0];
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const nextValue = input[i];
|
||||
if (nextValue === currentValue) {
|
||||
currentRunLength++;
|
||||
}
|
||||
else {
|
||||
// End of the current run, record it
|
||||
runLengths.push(currentRunLength);
|
||||
runValues.push(currentValue);
|
||||
// Start a new run
|
||||
currentValue = nextValue;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
}
|
||||
// Record the final run after the loop finishes
|
||||
runLengths.push(currentRunLength);
|
||||
runValues.push(currentValue);
|
||||
// Combine lengths and values into the final structured output array (BigUint64Array)
|
||||
const numRuns = runLengths.length;
|
||||
const encodedData = new BigUint64Array(numRuns * 2);
|
||||
// Populate the first half with lengths, converting the run length numbers to bigint for storage in the BigUint64Array.
|
||||
for (let i = 0; i < numRuns; i++) {
|
||||
encodedData[i] = BigInt(runLengths[i]);
|
||||
}
|
||||
// Populate the second half with values, offset by the total number of runs
|
||||
encodedData.set(runValues, numRuns);
|
||||
return { data: encodedData, runs: numRuns };
|
||||
}
|
||||
export function encodeUnsignedRleFloat64(input) {
|
||||
if (input.length === 0) {
|
||||
return { data: new Float64Array(0), runs: 0 };
|
||||
}
|
||||
const runLengths = [];
|
||||
const runValues = [];
|
||||
let currentRunLength = 0;
|
||||
let currentValue = input[0];
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const nextValue = input[i];
|
||||
if (nextValue === currentValue) {
|
||||
currentRunLength++;
|
||||
}
|
||||
else {
|
||||
// End of the current run, record it
|
||||
runLengths.push(currentRunLength);
|
||||
runValues.push(currentValue);
|
||||
// Start a new run
|
||||
currentValue = nextValue;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
}
|
||||
// Record the final run after the loop finishes
|
||||
runLengths.push(currentRunLength);
|
||||
runValues.push(currentValue);
|
||||
// Combine lengths and values into the final structured output array (Float64Array)
|
||||
const numRuns = runLengths.length;
|
||||
// The final array is twice the size of the number of runs
|
||||
const encodedData = new Float64Array(numRuns * 2);
|
||||
// Populate the first half with lengths
|
||||
encodedData.set(runLengths, 0);
|
||||
// Populate the second half with values, offset by the total number of runs
|
||||
encodedData.set(runValues, numRuns);
|
||||
return { data: encodedData, runs: numRuns };
|
||||
}
|
||||
export function encodeZigZagDeltaInt32(data) {
|
||||
if (data.length === 0) {
|
||||
return new Uint32Array(0);
|
||||
}
|
||||
const encodedData = new Uint32Array(data.length);
|
||||
let previousValue = data[0];
|
||||
encodedData[0] = encodeZigZagInt32Value(previousValue);
|
||||
for (let i = 1; i < data.length; i++) {
|
||||
const currentValue = data[i];
|
||||
const delta = currentValue - previousValue;
|
||||
const encodedDelta = encodeZigZagInt32Value(delta);
|
||||
// Store the encoded delta back into the array
|
||||
encodedData[i] = encodedDelta;
|
||||
// Update the previous value tracker for the next iteration's delta calculation
|
||||
previousValue = currentValue;
|
||||
}
|
||||
return encodedData;
|
||||
}
|
||||
export function encodeZigZagDeltaInt64(data) {
|
||||
if (data.length === 0) {
|
||||
return new BigUint64Array(0);
|
||||
}
|
||||
const encodedData = new BigUint64Array(data.length);
|
||||
let previousValue = data[0];
|
||||
encodedData[0] = encodeZigZagInt64Value(previousValue);
|
||||
for (let i = 1; i < data.length; i++) {
|
||||
const currentValue = data[i];
|
||||
const delta = currentValue - previousValue;
|
||||
const encodedDelta = encodeZigZagInt64Value(delta);
|
||||
// Store the encoded delta back into the array
|
||||
encodedData[i] = encodedDelta;
|
||||
// Update the previous value tracker for the next iteration's delta calculation
|
||||
previousValue = currentValue;
|
||||
}
|
||||
return encodedData;
|
||||
}
|
||||
export function encodeZigZagDeltaFloat64(data) {
|
||||
if (data.length === 0) {
|
||||
return;
|
||||
}
|
||||
let previousValue = data[0];
|
||||
data[0] = encodeZigZagFloat64Value(previousValue);
|
||||
for (let i = 1; i < data.length; i++) {
|
||||
const currentValue = data[i];
|
||||
const delta = currentValue - previousValue;
|
||||
const encodedDelta = encodeZigZagFloat64Value(delta);
|
||||
// Store the encoded delta back into the array
|
||||
data[i] = encodedDelta;
|
||||
// Update the previous value tracker for the next iteration's delta calculation
|
||||
previousValue = currentValue;
|
||||
}
|
||||
}
|
||||
export function encodeZigZagRleInt32(input) {
|
||||
if (input.length === 0) {
|
||||
return { data: new Uint32Array(0), runs: 0, numTotalValues: 0 };
|
||||
}
|
||||
const zigzagEncodedStream = [];
|
||||
// Step 1: Apply Zigzag Encoding to all values
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
zigzagEncodedStream.push(encodeZigZagInt32Value(input[i]));
|
||||
}
|
||||
// zigzagEncodedStream now holds the intermediate stream of zigzag values
|
||||
// Step 2: Apply RLE to the stream of zigzag-encoded values
|
||||
const runLengths = [];
|
||||
const runZigZagValues = [];
|
||||
let currentRunLength = 0;
|
||||
let currentValue = zigzagEncodedStream[0];
|
||||
for (let i = 0; i < zigzagEncodedStream.length; i++) {
|
||||
const nextValue = zigzagEncodedStream[i];
|
||||
if (nextValue === currentValue) {
|
||||
currentRunLength++;
|
||||
}
|
||||
else {
|
||||
runLengths.push(currentRunLength);
|
||||
runZigZagValues.push(currentValue);
|
||||
currentValue = nextValue;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
}
|
||||
// Record the final run
|
||||
runLengths.push(currentRunLength);
|
||||
runZigZagValues.push(currentValue);
|
||||
// Step 3: Combine lengths and values into the final structured output array
|
||||
const numRuns = runLengths.length;
|
||||
// The final array uses Uint32Array for lengths AND values
|
||||
const encodedData = new Uint32Array(numRuns * 2);
|
||||
// Populate the first half with lengths
|
||||
encodedData.set(runLengths, 0);
|
||||
// Populate the second half with zigzagged values
|
||||
encodedData.set(runZigZagValues, numRuns);
|
||||
return {
|
||||
data: encodedData,
|
||||
runs: numRuns,
|
||||
numTotalValues: input.length, // Total original values count
|
||||
};
|
||||
}
|
||||
export function encodeZigZagRleInt64(input) {
|
||||
if (input.length === 0) {
|
||||
return { data: new BigUint64Array(0), runs: 0, numTotalValues: 0 };
|
||||
}
|
||||
const zigzagEncodedStream = [];
|
||||
// Step 1: Apply Zigzag Encoding to all values
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
zigzagEncodedStream.push(encodeZigZagInt64Value(input[i]));
|
||||
}
|
||||
// zigzagEncodedStream now holds the intermediate stream of zigzag values
|
||||
// Step 2: Apply RLE to the stream of zigzag-encoded values
|
||||
const runLengths = [];
|
||||
const runZigZagValues = [];
|
||||
let currentRunLength = 0;
|
||||
let currentValue = zigzagEncodedStream[0];
|
||||
for (let i = 0; i < zigzagEncodedStream.length; i++) {
|
||||
const nextValue = zigzagEncodedStream[i];
|
||||
if (nextValue === currentValue) {
|
||||
currentRunLength++;
|
||||
}
|
||||
else {
|
||||
runLengths.push(currentRunLength);
|
||||
runZigZagValues.push(currentValue);
|
||||
currentValue = nextValue;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
}
|
||||
// Record the final run
|
||||
runLengths.push(currentRunLength);
|
||||
runZigZagValues.push(currentValue);
|
||||
// Step 3: Combine lengths and values into the final structured output array
|
||||
const numRuns = runLengths.length;
|
||||
// The final array uses BigUint64Array for lengths AND values
|
||||
const encodedData = new BigUint64Array(numRuns * 2);
|
||||
// Populate the first half with lengths (converting numbers back to BigUint64Array format)
|
||||
for (let i = 0; i < numRuns; i++) {
|
||||
encodedData[i] = BigInt(runLengths[i]);
|
||||
}
|
||||
// Populate the second half with zigzagged values
|
||||
encodedData.set(runZigZagValues, numRuns);
|
||||
return {
|
||||
data: encodedData,
|
||||
runs: numRuns,
|
||||
numTotalValues: input.length, // Total original values count
|
||||
};
|
||||
}
|
||||
export function encodeZigZagRleFloat64(input) {
|
||||
if (input.length === 0) {
|
||||
return { data: new Float64Array(0), runs: 0, numTotalValues: 0 };
|
||||
}
|
||||
const zigzagEncodedStream = [];
|
||||
// Step 1: Apply Float-based Zigzag Encoding to all values
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
zigzagEncodedStream.push(encodeZigZagFloat64Value(input[i]));
|
||||
}
|
||||
// zigzagEncodedStream now holds the intermediate stream of zigzag values (as floats acting as integers)
|
||||
// Step 2: Apply RLE to the stream of zigzag-encoded values
|
||||
const runLengths = [];
|
||||
const runZigZagValues = [];
|
||||
let currentRunLength = 0;
|
||||
let currentValue = zigzagEncodedStream[0];
|
||||
for (let i = 0; i < zigzagEncodedStream.length; i++) {
|
||||
const nextValue = zigzagEncodedStream[i];
|
||||
if (nextValue === currentValue) {
|
||||
currentRunLength++;
|
||||
}
|
||||
else {
|
||||
runLengths.push(currentRunLength);
|
||||
runZigZagValues.push(currentValue);
|
||||
currentValue = nextValue;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
}
|
||||
// Record the final run
|
||||
runLengths.push(currentRunLength);
|
||||
runZigZagValues.push(currentValue);
|
||||
// Step 3: Combine lengths and values into the final structured output array
|
||||
const numRuns = runLengths.length;
|
||||
// The final array uses Float64Array for lengths AND values
|
||||
const encodedData = new Float64Array(numRuns * 2);
|
||||
// Populate the first half with lengths
|
||||
encodedData.set(runLengths, 0);
|
||||
// Populate the second half with zigzagged values
|
||||
encodedData.set(runZigZagValues, numRuns);
|
||||
return {
|
||||
data: encodedData,
|
||||
runs: numRuns,
|
||||
numTotalValues: input.length, // Total original values count
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This is not really a encode, but more of a decode method...
|
||||
*/
|
||||
export function encodeDeltaInt32(data) {
|
||||
if (data.length === 0) {
|
||||
return;
|
||||
}
|
||||
for (let i = data.length - 1; i >= 1; i--) {
|
||||
data[i] = data[i] - data[i - 1];
|
||||
}
|
||||
}
|
||||
export function encodeComponentwiseDeltaVec2(data) {
|
||||
if (data.length < 2)
|
||||
return new Uint32Array(data);
|
||||
const encoded = new Uint32Array(data.length);
|
||||
// Reverse iterate to avoid overwriting data needed for delta computation
|
||||
for (let i = data.length - 2; i >= 2; i -= 2) {
|
||||
const deltaX = data[i] - data[i - 2];
|
||||
const deltaY = data[i + 1] - data[i - 1];
|
||||
encoded[i] = encodeZigZagInt32Value(deltaX);
|
||||
encoded[i + 1] = encodeZigZagInt32Value(deltaY);
|
||||
}
|
||||
// Encode first vertex last (after computing all deltas)
|
||||
encoded[0] = encodeZigZagInt32Value(data[0]);
|
||||
encoded[1] = encodeZigZagInt32Value(data[1]);
|
||||
return encoded;
|
||||
}
|
||||
export function encodeComponentwiseDeltaVec2Scaled(data, scale) {
|
||||
if (data.length < 2)
|
||||
return new Uint32Array(data);
|
||||
const encoded = new Uint32Array(data.length);
|
||||
// First, inverse scale all values (tile space -> original space)
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
encoded[i] = Math.round(data[i] / scale);
|
||||
}
|
||||
// Then apply componentwise delta encoding (same as non-scaled version)
|
||||
// Reverse iterate to avoid overwriting data needed for delta computation
|
||||
for (let i = encoded.length - 2; i >= 2; i -= 2) {
|
||||
const deltaX = encoded[i] - encoded[i - 2];
|
||||
const deltaY = encoded[i + 1] - encoded[i - 1];
|
||||
encoded[i] = encodeZigZagInt32Value(deltaX);
|
||||
encoded[i + 1] = encodeZigZagInt32Value(deltaY);
|
||||
}
|
||||
// Encode first vertex last (after computing all deltas)
|
||||
encoded[0] = encodeZigZagInt32Value(encoded[0]);
|
||||
encoded[1] = encodeZigZagInt32Value(encoded[1]);
|
||||
return encoded;
|
||||
}
|
||||
// HM TODO:
|
||||
// zigZagDeltaOfDeltaDecoding
|
||||
export function encodeZigZagRleDeltaInt32(values) {
|
||||
if (values.length === 0) {
|
||||
return { data: new Uint32Array(0), runs: 0, numTotalValues: 0 };
|
||||
}
|
||||
const runLengths = [];
|
||||
const encodedDeltas = [];
|
||||
// The decoder explicitly sets decodedValues[0] = 0 and uses previousValue = 0.
|
||||
// Therefore, we initialize our 'previous' tracker to 0 to calculate the first delta correctly.
|
||||
let previousValue = 0;
|
||||
// Variables to track the current run
|
||||
let currentDelta = null;
|
||||
let currentRunLength = 0;
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const value = values[i];
|
||||
const delta = value - previousValue;
|
||||
previousValue = value;
|
||||
if (currentDelta === null) {
|
||||
// First element initialization
|
||||
currentDelta = delta;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
else if (delta === currentDelta) {
|
||||
// Continuation of the current run
|
||||
currentRunLength++;
|
||||
}
|
||||
else {
|
||||
// The run has broken (delta changed)
|
||||
// 1. Push the length of the previous run
|
||||
runLengths.push(currentRunLength);
|
||||
// 2. ZigZag encode the previous delta and push it
|
||||
encodedDeltas.push(encodeZigZagInt32Value(currentDelta));
|
||||
// Start the new run
|
||||
currentDelta = delta;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
}
|
||||
// Flush the final run remaining after the loop finishes
|
||||
if (currentDelta !== null) {
|
||||
runLengths.push(currentRunLength);
|
||||
encodedDeltas.push(encodeZigZagInt32Value(currentDelta));
|
||||
}
|
||||
const numRuns = runLengths.length;
|
||||
// The decoder expects 'data' to be: [RunLength 1, RunLength 2... | Value 1, Value 2...]
|
||||
// Size is numRuns * 2 (First half lengths, second half values)
|
||||
const data = new Uint32Array(numRuns * 2);
|
||||
for (let i = 0; i < numRuns; i++) {
|
||||
data[i] = runLengths[i]; // First half: Run Lengths
|
||||
data[i + numRuns] = encodedDeltas[i]; // Second half: ZigZag Encoded Deltas
|
||||
}
|
||||
return {
|
||||
data: data,
|
||||
runs: numRuns,
|
||||
numTotalValues: values.length,
|
||||
};
|
||||
}
|
||||
export function encodeRleDeltaInt32(values) {
|
||||
if (values.length === 0) {
|
||||
return { data: new Uint32Array(0), runs: 0, numTotalValues: 0 };
|
||||
}
|
||||
const runLengths = [];
|
||||
const deltas = [];
|
||||
// The decoder logic relies on: decodedValues[0] = 0; previousValue = 0;
|
||||
// So the encoder must assume the sequence starts relative to 0.
|
||||
let previousValue = 0;
|
||||
// Track the current run of deltas
|
||||
let currentDelta = null;
|
||||
let currentRunLength = 0;
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const value = values[i];
|
||||
const delta = value - previousValue;
|
||||
previousValue = value;
|
||||
if (currentDelta === null) {
|
||||
// Initialize first run
|
||||
currentDelta = delta;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
else if (delta === currentDelta) {
|
||||
// Continue current run
|
||||
currentRunLength++;
|
||||
}
|
||||
else {
|
||||
// Delta changed: flush the previous run
|
||||
runLengths.push(currentRunLength);
|
||||
deltas.push(currentDelta);
|
||||
// Start new run
|
||||
currentDelta = delta;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
}
|
||||
// Flush the final run
|
||||
if (currentDelta !== null) {
|
||||
runLengths.push(currentRunLength);
|
||||
deltas.push(currentDelta);
|
||||
}
|
||||
const numRuns = runLengths.length;
|
||||
// Pack into Uint32Array: [ RunLength 1...N | Delta 1...N ]
|
||||
const data = new Uint32Array(numRuns * 2);
|
||||
for (let i = 0; i < numRuns; i++) {
|
||||
data[i] = runLengths[i];
|
||||
data[i + numRuns] = deltas[i];
|
||||
}
|
||||
return {
|
||||
data: data,
|
||||
runs: numRuns,
|
||||
numTotalValues: values.length,
|
||||
};
|
||||
}
|
||||
export function encodeDeltaRleInt32(input) {
|
||||
if (input.length === 0) {
|
||||
return { data: new Uint32Array(0), runs: 0, numValues: 0 };
|
||||
}
|
||||
const deltasAndEncoded = [];
|
||||
let previousValue = 0;
|
||||
// Step 1 & 2: Calculate Deltas and Zigzag Encode them
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const currentValue = input[i];
|
||||
const delta = currentValue - previousValue;
|
||||
const encodedDelta = encodeZigZagInt32Value(delta);
|
||||
deltasAndEncoded.push(encodedDelta);
|
||||
previousValue = currentValue;
|
||||
}
|
||||
// deltasAndEncoded now holds the intermediate stream of zigzagged deltas
|
||||
// Step 3: Apply RLE to the stream of zigzag-encoded deltas
|
||||
const runLengths = [];
|
||||
const runZigZagDeltas = [];
|
||||
let currentRunLength = 0;
|
||||
let currentRunValue = deltasAndEncoded[0];
|
||||
for (let i = 0; i < deltasAndEncoded.length; i++) {
|
||||
const nextValue = deltasAndEncoded[i];
|
||||
if (nextValue === currentRunValue) {
|
||||
currentRunLength++;
|
||||
}
|
||||
else {
|
||||
runLengths.push(currentRunLength);
|
||||
runZigZagDeltas.push(currentRunValue);
|
||||
currentRunValue = nextValue;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
}
|
||||
// Record the final run
|
||||
runLengths.push(currentRunLength);
|
||||
runZigZagDeltas.push(currentRunValue);
|
||||
// Step 4: Combine lengths and values into the final structured output array
|
||||
const numRuns = runLengths.length;
|
||||
const encodedData = new Uint32Array(numRuns * 2);
|
||||
// Populate the first half with lengths
|
||||
for (let i = 0; i < numRuns; i++) {
|
||||
encodedData[i] = runLengths[i];
|
||||
}
|
||||
// Populate the second half with zigzagged deltas
|
||||
// Uint32Array.set() works with standard number arrays
|
||||
encodedData.set(runZigZagDeltas, numRuns);
|
||||
return {
|
||||
data: encodedData,
|
||||
runs: numRuns,
|
||||
numValues: input.length, // Total original values count
|
||||
};
|
||||
}
|
||||
export function encodeDeltaRleInt64(input) {
|
||||
if (input.length === 0) {
|
||||
return { data: new BigUint64Array(0), runs: 0, numValues: 0 };
|
||||
}
|
||||
const deltasAndEncoded = [];
|
||||
let previousValue = 0n;
|
||||
// Step 1 & 2: Calculate Deltas and Zigzag Encode them
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const currentValue = input[i];
|
||||
const delta = currentValue - previousValue;
|
||||
const encodedDelta = encodeZigZagInt64Value(delta);
|
||||
deltasAndEncoded.push(encodedDelta);
|
||||
previousValue = currentValue;
|
||||
}
|
||||
// deltasAndEncoded now holds the intermediate stream of zigzagged deltas
|
||||
// Step 3: Apply RLE to the stream of zigzag-encoded deltas
|
||||
const runLengths = [];
|
||||
const runZigZagDeltas = [];
|
||||
let currentRunLength = 0;
|
||||
let currentValue = deltasAndEncoded[0];
|
||||
for (let i = 0; i < deltasAndEncoded.length; i++) {
|
||||
const nextValue = deltasAndEncoded[i];
|
||||
if (nextValue === currentValue) {
|
||||
currentRunLength++;
|
||||
}
|
||||
else {
|
||||
runLengths.push(currentRunLength);
|
||||
runZigZagDeltas.push(currentValue);
|
||||
currentValue = nextValue;
|
||||
currentRunLength = 1;
|
||||
}
|
||||
}
|
||||
// Record the final run
|
||||
runLengths.push(currentRunLength);
|
||||
runZigZagDeltas.push(currentValue);
|
||||
// Step 4: Combine lengths and values into the final structured output array
|
||||
const numRuns = runLengths.length;
|
||||
const encodedData = new BigUint64Array(numRuns * 2);
|
||||
// Populate the first half with lengths (converting numbers back to BigUint64Array for storage)
|
||||
for (let i = 0; i < numRuns; i++) {
|
||||
encodedData[i] = BigInt(runLengths[i]);
|
||||
}
|
||||
// Populate the second half with zigzagged deltas
|
||||
encodedData.set(runZigZagDeltas, numRuns);
|
||||
return {
|
||||
data: encodedData,
|
||||
runs: numRuns,
|
||||
numValues: input.length, // Total original values count
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=integerEncodingUtils.js.map
|
||||
Reference in New Issue
Block a user