ordered-binary 1.5.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/dist/index.cjs +21 -14
- package/index.js +21 -14
- package/package.json +1 -1
- package/tests/test.js +2 -0
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
[](https://www.npmjs.org/package/ordered-binary)
|
|
2
2
|
[](https://www.npmjs.org/package/ordered-binary)
|
|
3
3
|
[](LICENSE)
|
|
4
|
-
<a href="https://dev.doctorevidence.com/"><img src="./assets/powers-dre.png" width="203" /></a>
|
|
5
4
|
|
|
6
5
|
The ordered-binary package provides a representation of JavaScript primitives, serialized into binary format (NodeJS Buffers or Uint8Arrays), such that the binary values are naturally ordered such that it matches the natural ordering or values. For example, since -2.0321 > -2.04, then `toBufferKey(-2.0321)` will be greater than `toBufferKey(-2.04)` as a binary representation, in left-to-right evaluation. This is particular useful for storing keys as binaries with something like LMDB or LevelDB, to avoid any custom sorting.
|
|
7
6
|
|
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,12 @@ control character types:
|
|
|
20
20
|
|
|
21
21
|
const float64Array = new Float64Array(2);
|
|
22
22
|
const int32Array = new Int32Array(float64Array.buffer, 0, 4);
|
|
23
|
+
const {lowIdx, highIdx} = (() => {
|
|
24
|
+
if (new Uint8Array(new Uint32Array([0xFFEE1100]).buffer)[0] === 0xFF) {
|
|
25
|
+
return { lowIdx: 1, highIdx: 0 };
|
|
26
|
+
}
|
|
27
|
+
return { lowIdx: 0, highIdx: 1 };
|
|
28
|
+
})();
|
|
23
29
|
let nullTerminate = false;
|
|
24
30
|
let textEncoder;
|
|
25
31
|
try {
|
|
@@ -69,7 +75,7 @@ function writeKey(key, target, position, inSequence) {
|
|
|
69
75
|
}
|
|
70
76
|
} else {
|
|
71
77
|
if (target.utf8Write)
|
|
72
|
-
position += target.utf8Write(key, position,
|
|
78
|
+
position += target.utf8Write(key, position, target.byteLength - position);
|
|
73
79
|
else
|
|
74
80
|
position += textEncoder.encodeInto(key, target.subarray(position)).written;
|
|
75
81
|
if (position > target.length - 4)
|
|
@@ -78,8 +84,8 @@ function writeKey(key, target, position, inSequence) {
|
|
|
78
84
|
break
|
|
79
85
|
case 'number':
|
|
80
86
|
float64Array[0] = key;
|
|
81
|
-
let lowInt = int32Array[
|
|
82
|
-
let highInt = int32Array[
|
|
87
|
+
let lowInt = int32Array[lowIdx];
|
|
88
|
+
let highInt = int32Array[highIdx];
|
|
83
89
|
let length;
|
|
84
90
|
if (key < 0) {
|
|
85
91
|
targetView.setInt32(position + 4, ~((lowInt >>> 4) | (highInt << 28)));
|
|
@@ -127,18 +133,18 @@ function writeKey(key, target, position, inSequence) {
|
|
|
127
133
|
if (BigInt(asFloat) > key) {
|
|
128
134
|
float64Array[0] = asFloat;
|
|
129
135
|
if (asFloat > 0) {
|
|
130
|
-
if (int32Array[
|
|
131
|
-
int32Array[
|
|
136
|
+
if (int32Array[lowIdx])
|
|
137
|
+
int32Array[lowIdx]--;
|
|
132
138
|
else {
|
|
133
|
-
int32Array[
|
|
134
|
-
int32Array[
|
|
139
|
+
int32Array[highIdx]--;
|
|
140
|
+
int32Array[lowIdx] = 0xffffffff;
|
|
135
141
|
}
|
|
136
142
|
} else {
|
|
137
|
-
if (int32Array[
|
|
138
|
-
int32Array[
|
|
143
|
+
if (int32Array[lowIdx] < 0xffffffff)
|
|
144
|
+
int32Array[lowIdx]++;
|
|
139
145
|
else {
|
|
140
|
-
int32Array[
|
|
141
|
-
int32Array[
|
|
146
|
+
int32Array[highIdx]++;
|
|
147
|
+
int32Array[lowIdx] = 0;
|
|
142
148
|
}
|
|
143
149
|
}
|
|
144
150
|
asFloat = float64Array[0];
|
|
@@ -148,7 +154,7 @@ function writeKey(key, target, position, inSequence) {
|
|
|
148
154
|
return writeKey(asFloat, target, position, inSequence)
|
|
149
155
|
writeKey(asFloat, target, position, inSequence);
|
|
150
156
|
position += 9; // always increment by 9 if we are adding fractional bits
|
|
151
|
-
let exponent = BigInt((int32Array[
|
|
157
|
+
let exponent = BigInt((int32Array[highIdx] >> 20 & 0x7ff) - 1079);
|
|
152
158
|
let nextByte = difference >> exponent;
|
|
153
159
|
target[position - 1] |= Number(nextByte);
|
|
154
160
|
difference -= nextByte << exponent;
|
|
@@ -222,8 +228,8 @@ function readKey(buffer, start, end, inSequence) {
|
|
|
222
228
|
highInt = highInt ^ 0x7fffffff;
|
|
223
229
|
lowInt = ~lowInt;
|
|
224
230
|
}
|
|
225
|
-
int32Array[
|
|
226
|
-
int32Array[
|
|
231
|
+
int32Array[highIdx] = highInt;
|
|
232
|
+
int32Array[lowIdx] = lowInt;
|
|
227
233
|
value = float64Array[0];
|
|
228
234
|
position += 9;
|
|
229
235
|
if (size > 9 && buffer[position] > 0) {
|
|
@@ -243,6 +249,7 @@ function readKey(buffer, start, end, inSequence) {
|
|
|
243
249
|
position++;
|
|
244
250
|
}
|
|
245
251
|
value = readStringSafely(buffer, end);
|
|
252
|
+
if (position < end) position--; // if have a null terminator for the string, count that as the array separator
|
|
246
253
|
}
|
|
247
254
|
while (position < end) {
|
|
248
255
|
if (buffer[position] === 0)
|
package/index.js
CHANGED
|
@@ -16,6 +16,12 @@ control character types:
|
|
|
16
16
|
|
|
17
17
|
const float64Array = new Float64Array(2)
|
|
18
18
|
const int32Array = new Int32Array(float64Array.buffer, 0, 4)
|
|
19
|
+
const {lowIdx, highIdx} = (() => {
|
|
20
|
+
if (new Uint8Array(new Uint32Array([0xFFEE1100]).buffer)[0] === 0xFF) {
|
|
21
|
+
return { lowIdx: 1, highIdx: 0 };
|
|
22
|
+
}
|
|
23
|
+
return { lowIdx: 0, highIdx: 1 };
|
|
24
|
+
})();
|
|
19
25
|
let nullTerminate = false
|
|
20
26
|
let textEncoder
|
|
21
27
|
try {
|
|
@@ -65,7 +71,7 @@ export function writeKey(key, target, position, inSequence) {
|
|
|
65
71
|
}
|
|
66
72
|
} else {
|
|
67
73
|
if (target.utf8Write)
|
|
68
|
-
position += target.utf8Write(key, position,
|
|
74
|
+
position += target.utf8Write(key, position, target.byteLength - position)
|
|
69
75
|
else
|
|
70
76
|
position += textEncoder.encodeInto(key, target.subarray(position)).written
|
|
71
77
|
if (position > target.length - 4)
|
|
@@ -74,8 +80,8 @@ export function writeKey(key, target, position, inSequence) {
|
|
|
74
80
|
break
|
|
75
81
|
case 'number':
|
|
76
82
|
float64Array[0] = key
|
|
77
|
-
let lowInt = int32Array[
|
|
78
|
-
let highInt = int32Array[
|
|
83
|
+
let lowInt = int32Array[lowIdx]
|
|
84
|
+
let highInt = int32Array[highIdx]
|
|
79
85
|
let length
|
|
80
86
|
if (key < 0) {
|
|
81
87
|
targetView.setInt32(position + 4, ~((lowInt >>> 4) | (highInt << 28)))
|
|
@@ -123,18 +129,18 @@ export function writeKey(key, target, position, inSequence) {
|
|
|
123
129
|
if (BigInt(asFloat) > key) {
|
|
124
130
|
float64Array[0] = asFloat;
|
|
125
131
|
if (asFloat > 0) {
|
|
126
|
-
if (int32Array[
|
|
127
|
-
int32Array[
|
|
132
|
+
if (int32Array[lowIdx])
|
|
133
|
+
int32Array[lowIdx]--;
|
|
128
134
|
else {
|
|
129
|
-
int32Array[
|
|
130
|
-
int32Array[
|
|
135
|
+
int32Array[highIdx]--;
|
|
136
|
+
int32Array[lowIdx] = 0xffffffff;
|
|
131
137
|
}
|
|
132
138
|
} else {
|
|
133
|
-
if (int32Array[
|
|
134
|
-
int32Array[
|
|
139
|
+
if (int32Array[lowIdx] < 0xffffffff)
|
|
140
|
+
int32Array[lowIdx]++;
|
|
135
141
|
else {
|
|
136
|
-
int32Array[
|
|
137
|
-
int32Array[
|
|
142
|
+
int32Array[highIdx]++;
|
|
143
|
+
int32Array[lowIdx] = 0;
|
|
138
144
|
}
|
|
139
145
|
}
|
|
140
146
|
asFloat = float64Array[0];
|
|
@@ -144,7 +150,7 @@ export function writeKey(key, target, position, inSequence) {
|
|
|
144
150
|
return writeKey(asFloat, target, position, inSequence)
|
|
145
151
|
writeKey(asFloat, target, position, inSequence)
|
|
146
152
|
position += 9; // always increment by 9 if we are adding fractional bits
|
|
147
|
-
let exponent = BigInt((int32Array[
|
|
153
|
+
let exponent = BigInt((int32Array[highIdx] >> 20 & 0x7ff) - 1079);
|
|
148
154
|
let nextByte = difference >> exponent;
|
|
149
155
|
target[position - 1] |= Number(nextByte);
|
|
150
156
|
difference -= nextByte << exponent;
|
|
@@ -218,8 +224,8 @@ export function readKey(buffer, start, end, inSequence) {
|
|
|
218
224
|
highInt = highInt ^ 0x7fffffff
|
|
219
225
|
lowInt = ~lowInt
|
|
220
226
|
}
|
|
221
|
-
int32Array[
|
|
222
|
-
int32Array[
|
|
227
|
+
int32Array[highIdx] = highInt
|
|
228
|
+
int32Array[lowIdx] = lowInt
|
|
223
229
|
value = float64Array[0]
|
|
224
230
|
position += 9
|
|
225
231
|
if (size > 9 && buffer[position] > 0) {
|
|
@@ -239,6 +245,7 @@ export function readKey(buffer, start, end, inSequence) {
|
|
|
239
245
|
position++
|
|
240
246
|
}
|
|
241
247
|
value = readStringSafely(buffer, end)
|
|
248
|
+
if (position < end) position-- // if have a null terminator for the string, count that as the array separator
|
|
242
249
|
}
|
|
243
250
|
while (position < end) {
|
|
244
251
|
if (buffer[position] === 0)
|
package/package.json
CHANGED
package/tests/test.js
CHANGED
|
@@ -111,6 +111,8 @@ suite('key buffers', () => {
|
|
|
111
111
|
[4, 5])
|
|
112
112
|
assert.deepEqual(fromBufferKey(toBufferKey(['hello', 5.25])),
|
|
113
113
|
['hello', 5.25])
|
|
114
|
+
assert.deepEqual(fromBufferKey(toBufferKey([5, 'hello', null, 5.25])),
|
|
115
|
+
[5, 'hello', null, 5.25])
|
|
114
116
|
assert.deepEqual(fromBufferKey(toBufferKey([true, 1503579323825])),
|
|
115
117
|
[true, 1503579323825])
|
|
116
118
|
assert.deepEqual(fromBufferKey(toBufferKey([-0.2525, 'sec\x00nd'])),
|