Skip to content

Commit 7f7d75e

Browse files
committed
Testing that lexicographic order is equal to Buffer.compare order and numeric order of buffer bytes
1 parent f4dec64 commit 7f7d75e

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

tests/DB.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { DBWorkerModule } from './workers/dbWorkerModule';
44
import os from 'os';
55
import path from 'path';
66
import fs from 'fs';
7+
import nodeCrypto from 'crypto';
78
import lexi from 'lexicographic-integer';
89
import Logger, { LogLevel, StreamHandler } from '@matrixai/logger';
910
import { WorkerManager } from '@matrixai/workers';
@@ -259,6 +260,29 @@ describe('DB', () => {
259260
expect(keys.sort()).toEqual(keysIterated);
260261
await db.stop();
261262
});
263+
test('lexicographic buffer iteration order', async () => {
264+
const dbPath = `${dataDir}/db`;
265+
const db = await DB.createDB({ dbPath, crypto, logger });
266+
const keys: Array<Buffer> = Array.from({ length: 100 }, () =>
267+
nodeCrypto.randomBytes(3),
268+
);
269+
for (const k of keys) {
270+
await db.put([], k, 'value');
271+
}
272+
const keysIterated: Array<Buffer> = [];
273+
for await (const k of db.db.createKeyStream()) {
274+
keysIterated.push(k as Buffer);
275+
}
276+
expect(keys).not.toStrictEqual(keysIterated);
277+
expect(keys.sort(Buffer.compare)).toStrictEqual(keysIterated);
278+
// Buffers can be considered can be considered big-endian numbers
279+
const keysNumeric = keys.map(utils.bytes2BigInt);
280+
// Therefore lexicographic ordering of buffers is equal to numeric ordering of bytes
281+
expect(
282+
keysNumeric.slice(1).every((item, i) => keysNumeric[i] <= item),
283+
).toBe(true);
284+
await db.stop();
285+
});
262286
test('lexicographic integer iteration', async () => {
263287
// Using the lexicographic-integer encoding
264288
const dbPath = `${dataDir}/db`;

tests/utils.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,40 @@ async function decrypt(
7272
return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
7373
}
7474

75+
/**
76+
* Positive base 10 numbers to hex string
77+
* Big-endian order
78+
* Use parseInt for vice-versa
79+
*/
80+
function dec2Hex(dec: number, size: number): string {
81+
dec %= 16 ** size;
82+
// `>>>` coerces dec to unsigned integer
83+
return (dec >>> 0).toString(16).padStart(size, '0');
84+
}
85+
86+
/**
87+
* Uint8Array to hex string
88+
*/
89+
function bytes2Hex(bytes: Uint8Array): string {
90+
return [...bytes].map((n) => dec2Hex(n, 2)).join('');
91+
}
92+
93+
/**
94+
* Uint8Array to Positive BigInt
95+
*/
96+
function bytes2BigInt(bytes: Uint8Array): bigint {
97+
const hex = bytes2Hex(bytes);
98+
return BigInt('0x' + hex);
99+
}
100+
75101
export {
76102
getRandomBytes,
77103
getRandomBytesSync,
78104
generateKey,
79105
generateKeySync,
80106
encrypt,
81107
decrypt,
108+
dec2Hex,
109+
bytes2Hex,
110+
bytes2BigInt,
82111
};

0 commit comments

Comments
 (0)