From bd7147f56bb40222dffc7e19688075b17527acf4 Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Tue, 2 Aug 2022 10:49:44 +0100 Subject: [PATCH] feat: add alloc and allocUnsafe (#31) Allows us to create `Uint8Array`s that reference unitialised memory where supported in order to improve performance. --- .aegir.cjs | 5 +---- README.md | 42 ++++++++++++++++++++++++++++++++++------ package.json | 3 +++ src/alloc.js | 30 ++++++++++++++++++++++++++++ test/alloc.spec.js | 25 ++++++++++++++++++++++++ test/from-string.spec.js | 2 +- 6 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 src/alloc.js create mode 100644 test/alloc.spec.js diff --git a/.aegir.cjs b/.aegir.cjs index 7b1391c..7c35036 100644 --- a/.aegir.cjs +++ b/.aegir.cjs @@ -5,10 +5,7 @@ module.exports = { build: { bundlesizeMax: '7KB', config: { - entryPoints: ['index.js'] + entryPoints: ['src/index.js'] } - }, - docs: { - entryPoint: 'index.js' } } diff --git a/README.md b/README.md index a922ff0..4bc4398 100644 --- a/README.md +++ b/README.md @@ -3,21 +3,51 @@ Some utility functions to make dealing with `Uint8Array`s more pleasant. - [API](#api) - - [compare(a, b)](#comparea-b) + - [alloc(size)](#allocsize) - [Example](#example) - - [concat(arrays, [length])](#concatarrays-length) + - [allocUnsafe(size)](#allocunsafesize) - [Example](#example-1) - - [equals(a, b)](#equalsa-b) + - [compare(a, b)](#comparea-b) - [Example](#example-2) - - [fromString(string, encoding = 'utf8')](#fromstringstring-encoding--utf8) + - [concat(arrays, [length])](#concatarrays-length) - [Example](#example-3) - - [toString(array, encoding = 'utf8')](#tostringarray-encoding--utf8) + - [equals(a, b)](#equalsa-b) - [Example](#example-4) - - [xor(a, b)](#xora-b) + - [fromString(string, encoding = 'utf8')](#fromstringstring-encoding--utf8) - [Example](#example-5) + - [toString(array, encoding = 'utf8')](#tostringarray-encoding--utf8) + - [Example](#example-6) + - [xor(a, b)](#xora-b) + - [Example](#example-7) ## API +### alloc(size) + +Create a new `Uint8Array`. If `globalThis.Buffer` is defined, it will be used in preference to `globalThis.Uint8Array`. + +#### Example + +```js +import { alloc } from 'uint8arrays/alloc` + +const buf = alloc(100) +``` + +### allocUnsafe(size) + +Create a new `Uint8Array`. If `globalThis.Buffer` is defined, it will be used in preference to `globalThis.Uint8Array`. + +On platforms that support it, memory referenced by the returned `Uint8Array` will not be initialized. + +#### Example + +```js +import { allocUnsafe } from 'uint8arrays/alloc` + +const buf = allocUnsafe(100) +``` + ### compare(a, b) Compare two `Uint8Arrays` diff --git a/package.json b/package.json index 38150e6..57602b7 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,9 @@ ".": { "import": "./src/index.js" }, + "./alloc": { + "import": "./src/alloc.js" + }, "./compare": { "import": "./src/compare.js" }, diff --git a/src/alloc.js b/src/alloc.js new file mode 100644 index 0000000..0a69a3d --- /dev/null +++ b/src/alloc.js @@ -0,0 +1,30 @@ +/** + * Returns a `Uint8Array` of the requested size. Referenced memory will + * be initialized to 0. + * + * @param {number} [size] + * @returns {Uint8Array} + */ +export function alloc (size = 0) { + if (globalThis.Buffer != null && globalThis.Buffer.alloc != null) { + return globalThis.Buffer.alloc(size) + } + + return new Uint8Array(size) +} + +/** + * Where possible returns a Uint8Array of the requested size that references + * uninitialized memory. Only use if you are certain you will immediately + * overwrite every value in the returned `Uint8Array`. + * + * @param {number} [size] + * @returns {Uint8Array} + */ +export function allocUnsafe (size = 0) { + if (globalThis.Buffer != null && globalThis.Buffer.allocUnsafe != null) { + return globalThis.Buffer.allocUnsafe(size) + } + + return new Uint8Array(size) +} diff --git a/test/alloc.spec.js b/test/alloc.spec.js new file mode 100644 index 0000000..ad07a2d --- /dev/null +++ b/test/alloc.spec.js @@ -0,0 +1,25 @@ +/* eslint-env mocha */ + +import { expect } from 'aegir/utils/chai.js' +import { alloc, allocUnsafe } from '../src/alloc.js' + +describe('Uint8Array alloc', () => { + it('can alloc memory', () => { + const size = 10 + + expect(alloc(size)).to.have.property('byteLength', size) + }) + + it('can alloc memory', () => { + const size = 10 + const buf = alloc(size) + + expect(buf.every(value => value === 0)).to.be.true() + }) + + it('can alloc memory unsafely', () => { + const size = 10 + + expect(allocUnsafe(size)).to.have.property('byteLength', size) + }) +}) diff --git a/test/from-string.spec.js b/test/from-string.spec.js index 50bbab8..ac2a81b 100644 --- a/test/from-string.spec.js +++ b/test/from-string.spec.js @@ -17,7 +17,7 @@ describe('Uint8Array fromString', () => { expect(fromString(str)).to.deep.equal(arr) }) - supportedBases.forEach(base => { + supportedBases.filter(base => base !== 'base256emoji').forEach(base => { it(`creates a Uint8Array from a ${base} string`, () => { const arr = Uint8Array.from([0, 1, 2, 3]) const str = toString(arr, base)