@vizidrix/libringbufferjs
v0.1.1
Published
Vizidrix - LibRingBufferJS provides a small suite of low level wrappers around a pre-allocated 2s compliment sized auto wrapping buffer
Downloads
3
Readme
Vizidrix - LibRingBufferJS
Goals
Provide a low level mechanism which avoids allocation and garbage collection overhead.
By enforcing ring counts as 2s compliments the wrapping mechanism is simplified from variable size rings, where head and tail index must be tracked in order to provide looping characteristics, down to a simple binary AND (&).
The goal of this library is to provide low level features that can be used to build higher order structures such as Queues and Pub/Sub that can take advantage of it's internal structure.
Inspired by ideas around mechanical sympathy:
Pre-allocated structures, data element which could be size aligned to optimize for cache lines
ringbuffer.ts
/**
* IRingBuffer provides access methods to interact with the ring buffer structure
*/
export interface IRingBuffer<T> {
/** returns a DataView of the current position and moves the position forward */
claim: () => T
/** returns the current bounded position used to index the ring internally */
getIndex: () => number
/** returns the current, perpetually incrementing, cursor position of the ring buffer */
getPosition: () => number
/** returns the ring's initialization data */
getRingSize: () => number
/** returns a slice cursor to the slice at the specified index within the ring */
peek: (index: number) => T
}
// example using BianryRingBuffer
import { BinaryRingBuffer } from 'libringbufferjs'
// make a binary ring buffer
let rb = BinaryRingBuffer(4, 16)
// claim a slot - gives a reference to the DataView in the current slot and moves the pointer
let writer = rb.claim()
// put binary data into the slice you claimed
writer.setInt8(0, 10)
// grab a slice cursor at a specified position
let reader = rb.peek(0)
// read the data out of the slice you previously wrote to
let value = reader.getInt8(0)
// example using RingBuffer
import { RingBuffer } from 'libringbufferjs'
// make a basic object ring buffer with a structure defined inline
let rb = RingBuffer(4, () => {return { value: 0 }})
// claim a slot = gives a reference to the object in the current slot and moves the pointer
let writer = rb.claim()
// update properties of your object
writer.value = 20
// grab an object reference at a specified position
let reader = rb.peek(0)
// read the data out of the object property
let value = reader.value
todo: implement non-binary ring buffer that can pre-fill object instances using a factory (optionally a reset function?) and claim returns a reference that can be mutated
Usefull libraries
Library
This library depends on TypeScript to compile:
Tips for setting up repo for NPM: Authoring NPM Modules with TypeScript
npm install -g typescript
Useful NPM Commands
Initializes a freshly cloned repo, downloading npm and typescript packages and other prep
Caution, this will delete files that aren't linked to Git
npm run setup
Builds the typescript command and generates the es5 compatible version
npm run compile
Runs the tslint utility which reports back any non-conforming instances
Helps to create a uniform code base by enforcing sytle and naming type of guidelines
npm run lint
Executes the 'tape' test suite and emits the results to the console
npm run test
Executes the benchmarkjs suite and emits the results to the console
npm run bench
Executes compile, lint and test functions and sets up a file watcher to trigger them on each file modification
npm run dev
Executes the typedoc utility which generates documentation for the project based upon the provided types, comments and structures
npm run docs
Hosted on GitLab
View Project Runners
GitLab CI - gitlab.com/vizidrix/typescript_lib_boilerplate
Setup Private Runners
Development Environment
- Typescript
- Add static typing and related utility to JS IDE
- TSLint
- TypeScript linter to enforce syntax and coding standards
- Tape / Blue-Tape
- Async Unit Testing callable from node
- Istanbul
- Test Coverage Report and Enforcement
- BenchmarkJS
- JavaScript benchmarking library
Support for multiple targets (es5 and es6) is difficult due to es5 required polyfills
Documentation
Keeping documentation up to date is hard, wherever possible keep it next to the item being documented so it stays live.
Setup a pre-commit step to trigger docs generation, need to check if it auto updates prior to commit
// Generate docs manually
npm run docs
Typescript Definitions
From DefiantlyTyped
- blue-tape
- es6-promise
- node
- tape
TSLint
TODO: Consider switching / implementing Standard JS
See TSLint - Github for more options and documentation
Excluded options:
"no-any": true,
"no-bitwise": true,
"no-conditional-assignment": true,
"no-constructor-vars": true,
BenchmarkJS
Bulletproof JavaScript Benchmarks
Publishing to NPM
npm publish --access=public
Interesting Stuff
JavaScript Performance Dev - Volkan Özçelik