Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Buffer with Uint8Array #452

Merged
merged 36 commits into from
Sep 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e1ba8ed
Replace Tap constructor with factory methods
valadaptive Dec 22, 2022
8a1379f
Remove utils.bufferFrom
valadaptive Jan 16, 2024
e92e52c
Remove utils.newBuffer
valadaptive Jan 16, 2024
e968a0a
Replace Buffer.slice with Buffer.subarray
valadaptive Dec 22, 2022
9a2db96
Encapsulate Tap.buf
valadaptive Dec 24, 2022
84edd1e
Loosen isBuffer checks to accept Uint8Array
valadaptive Dec 24, 2022
7daba22
WIP debufferify
valadaptive Jan 1, 2023
9e6b842
Add float benchmark
valadaptive Jan 10, 2024
a0be1cc
Finally fix perf woes
valadaptive Jan 10, 2024
61a1623
Manually trigger GC in perf
valadaptive Jan 16, 2024
eac545a
Improve text encode/decode performance
valadaptive Jan 16, 2024
a902cff
Remove shared buffer pool
valadaptive Jan 16, 2024
1195470
Remove BufferPool entirely
valadaptive Jan 16, 2024
c733678
Use exponential distribution for random strings
valadaptive Feb 23, 2024
5a6176a
Redo writeString without Buffer.byteLength
valadaptive Feb 24, 2024
6d56968
Polyfill Buffer.compare in browsers
valadaptive Feb 28, 2024
f1e6db8
Remove Buffer usage from (un)packLongBytes
valadaptive Feb 28, 2024
81b9626
Fix Buffer instance check in Tap#setData
valadaptive Mar 30, 2024
756e79f
Remove buffer imports
valadaptive Mar 30, 2024
b490a2f
Return Uint8Array from Lcg#nextBuffer
valadaptive Mar 30, 2024
048e9fb
Remove Buffer usage from containers.js
valadaptive Mar 30, 2024
d3b8973
Remove Buffer usage from index.js
valadaptive Mar 30, 2024
2017980
Remove Buffer usage from Type#fingerprint
valadaptive Sep 10, 2024
61cbab2
Replace Buffer.compare with utils.bufCompare
valadaptive Sep 10, 2024
898ce75
Polyfill BytesType._copy Buffer API usages
valadaptive Sep 10, 2024
108f177
Update comments in types.js
valadaptive Sep 10, 2024
23c9bea
Fix isBufferLike import
valadaptive Sep 13, 2024
42e97f6
Add bufEqual helper
valadaptive Sep 13, 2024
005b94b
Cache text encoding subarrays on-demand
valadaptive Sep 13, 2024
50a1e67
Further optimize string decoding
valadaptive Sep 13, 2024
f5c6858
Guard Buffer.prototype.latin1Slice as well
valadaptive Sep 13, 2024
b00b88d
Store cached fingerprint as string again
valadaptive Sep 16, 2024
3ae2c4d
Add comments on Buffer function specializations
valadaptive Sep 16, 2024
2f8a010
Fix setting this.pos in Tap#writeString
valadaptive Sep 16, 2024
3941f74
Make Tap#length a getter
valadaptive Sep 17, 2024
62b8e93
Revert StringType#random change
valadaptive Sep 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc
Submodule doc updated from bebd04 to b36b2f
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
'use strict';

let io = require('node-avro-io'),
avsc = require('../../../../lib');
avsc = require('../../../../lib'),
{isBufferLike} = require('../../../../lib/utils');


let loops = 2;
Expand All @@ -30,7 +31,7 @@ avsc.createFileDecoder(process.argv[2])
});

function deserialize(buffer) {
if (!Buffer.isBuffer(buffer)) {
if (!isBufferLike(buffer)) {
throw 'Buffer object expected';
}

Expand All @@ -44,7 +45,7 @@ function deserialize(buffer) {
this._i += len;
return len == 1 ?
buffer[i] :
buffer.slice(i, this._i);
buffer.subarray(i, this._i);
},
skip: function(len) {
if (this._i + len > buffer.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
'use strict';

let io = require('node-avro-io'),
avsc = require('../../../../lib');
avsc = require('../../../../lib'),
{isBufferLike} = require('../../../../lib/utils');


let loops = 2;
Expand Down Expand Up @@ -33,7 +34,7 @@ function serialize(datum) {
let buffer = Buffer.from([]);
let encoder = new io.IO.BinaryEncoder({
write: function(data) {
if (!Buffer.isBuffer(data)) {
if (!isBufferLike(data)) {
data = Buffer.from([data]);
}
buffer = Buffer.concat([buffer, data]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
'use strict';

let avro = require('etp-avro'),
{Buffer} = require('buffer'),
avsc = require('../../../../lib');


Expand Down Expand Up @@ -31,8 +32,8 @@ avsc.createFileDecoder(process.argv[2])
function loop() {
let n = 0;
for (let i = 0, l = records.length; i < l; i++) {
// We need to slice to force a copy otherwise the array is shared.
let buf = writer.encode(schema, records[i]).slice();
// We need to force a copy otherwise the array is shared.
let buf = Buffer.from(writer.encode(schema, records[i]));
n += buf[0] + buf.length;
}
return n;
Expand Down
3 changes: 2 additions & 1 deletion etc/benchmarks/js-serialization-libraries/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

let avro = require('../../../lib'),
{isBufferLike} = require('../../../../lib/utils'),
Benchmark = require('benchmark'),
commander = require('commander'),
compactr = require('compactr'),
Expand Down Expand Up @@ -285,7 +286,7 @@ class EncodeSuite extends Suite {
let val = this.getValue();
return function () {
let str = JSON.stringify(val, (key, value) => {
if (Buffer.isBuffer(value)) {
if (isBufferLike(value)) {
return value.toString('binary');
}
return value;
Expand Down
4 changes: 1 addition & 3 deletions etc/browser/avsc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
*/

let containers = require('../../lib/containers'),
utils = require('../../lib/utils'),
stream = require('stream');


/** Transform stream which lazily reads a blob's contents. */
class BlobReader extends stream.Readable {
constructor (blob, opts) {
Expand Down Expand Up @@ -39,7 +37,7 @@ class BlobReader extends stream.Readable {
if (evt.error) {
self.emit('error', evt.error);
} else {
self.push(utils.bufferFrom(reader.result));
self.push(reader.result);
}
}, false);
reader.readAsArrayBuffer(blob);
Expand Down
8 changes: 3 additions & 5 deletions etc/browser/lib/md5.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
*
*/

let buffer = require('buffer');
let Buffer = buffer.Buffer;

function md5cycle(x, k) {
let a = x[0], b = x[1], c = x[2], d = x[3];

Expand Down Expand Up @@ -148,9 +145,10 @@ function md5blk(s) {

function md5(s) {
let arr = md51(s);
let buf = Buffer.alloc(16);
let buf = new Uint8Array(16);
let dv = new DataView(buf.buffer);
for (let i = 0; i < 4; i++) {
buf.writeIntLE(arr[i], i * 4, 4);
dv.setInt32(i * 4, arr[i], true);
}
return buf;
}
Expand Down
10 changes: 10 additions & 0 deletions etc/schemas/Float.avsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "Float",
"type": "record",
"fields": [
{
"name": "value",
"type": "float"
}
]
}
4 changes: 3 additions & 1 deletion etc/scripts/infer
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ switch (argv.length) {
process.exit(1);
}

const DECODER = new TextDecoder();

/**
* Infer a type from a stream of serialized JSON values.
*
Expand All @@ -42,7 +44,7 @@ function fromStdin() {
let str = '';
process.stdin
.on('data', (buf) => {
str += buf.toString();
str += DECODER.decode(buf);
let pos;
while ((pos = utils.jsonEnd(str)) >= 0) {
let val = JSON.parse(str.slice(0, pos));
Expand Down
3 changes: 2 additions & 1 deletion etc/scripts/meta
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ META_TYPE.fromBuffer = function (buf) {
return avro.Type.forType(attrs, {wrapUnions: true});
};

const DECODER = new TextDecoder();

// Example of things we can do.
switch (process.argv[2]) {
Expand All @@ -141,7 +142,7 @@ switch (process.argv[2]) {
if (err) {
throw err;
}
let type = avro.Type.forSchema(buf.toString());
let type = avro.Type.forSchema(DECODER.decode(buf));
process.stdout.write(META_TYPE.toBuffer(type));
});
break;
Expand Down
11 changes: 11 additions & 0 deletions etc/scripts/perf
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ if (~index) {
// serialization speed).
let NUM_VALUES = 1000;

function maybeGC() {
try {
global.gc();
mtth marked this conversation as resolved.
Show resolved Hide resolved
} catch (err) {
// GC not exposed
}
}

// Header formatting is done according to GitHub flavored Markdown.
console.log(['fromBuffer', 'toBuffer', 'isValid ', '(ops/sec)'].join('\t| '));
console.log(['---------:', '-------:', '------: ', '---------'].join('\t| '));
Expand All @@ -58,6 +66,7 @@ paths.forEach((fpath) => {
stats.push(s);
});

maybeGC();
bench.clone({fn: function () {
for (let i = 0, l = NUM_VALUES; i < l; i++) {
let val = type.fromBuffer(bufs[i]);
Expand All @@ -67,6 +76,7 @@ paths.forEach((fpath) => {
}
}}).run();

maybeGC();
bench.clone({fn: function () {
for (let i = 0, l = NUM_VALUES; i < l; i++) {
let buf = type.toBuffer(values[i]);
Expand All @@ -76,6 +86,7 @@ paths.forEach((fpath) => {
}
}}).run();

maybeGC();
bench.clone({fn: function () {
for (let i = 0, l = NUM_VALUES; i < l; i++) {
if (!type.isValid(values[i])) {
Expand Down
Loading
Loading