You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
4.0 KiB
104 lines
4.0 KiB
bytewise-core |
|
============= |
|
|
|
Binary serialization of arbitrarily complex structures that sort element-wise |
|
|
|
[![build status](https://travis-ci.org/deanlandolt/bytewise-core.svg?branch=master)](https://travis-ci.org/deanlandolt/bytewise-core) |
|
|
|
Allows efficient comparison of a variety of useful data structures in a way that respects the sort order defined by [typewise](https://github.com/deanlandolt/typewise). |
|
|
|
This library defines a total order for well-structured keyspaces in key value stores. The ordering is a superset of the sorting algorithm defined by [IndexedDB](http://www.w3.org/TR/IndexedDB/#key-construct) and the one defined by [CouchDB](http://wiki.apache.org/couchdb/View_collation). This serialization makes it easy to take advantage of the benefits of structured indexing in systems with fast but naïve binary indexing (key/value databases). |
|
|
|
|
|
## Order of Supported Structures |
|
|
|
This package is a barebones kernel of [bytewise](https://github.com/deanlandolt/bytewise), containing only the structures most often used to create structured keyspaces. |
|
|
|
This is the top level order of the various structures that may be encoded: |
|
|
|
* `null` |
|
* `false` |
|
* `true` |
|
* `Number` (numeric) |
|
* `Date` (time-wise) |
|
* `Buffer`, `Uint8Array` (bit-wise) |
|
* `String` (character-wise) |
|
* `Array` (element-wise) |
|
* `undefined` |
|
|
|
Structured types like `Array` may recursively contain any other supported structures. |
|
|
|
|
|
## Usage |
|
|
|
`encode` serializes any supported type and returns a `Buffer`, or throws if an |
|
unsupported structure is provided. |
|
|
|
```js |
|
var assert = require('assert') |
|
var bytewise = require('./') |
|
var encode = bytewise.encode |
|
|
|
// Numbers are stored in 9 bytes -- 1 byte for the type tag and an 8 byte float |
|
assert.equal(encode(12345).toString('hex'), '4240c81c8000000000') |
|
// Negative numbers are stored as positive numbers, but with a lower type tag and their bits inverted |
|
assert.equal(encode(-12345).toString('hex'), '41bf37e37fffffffff') |
|
|
|
// The `toString` method of `Buffer` values returned by `encode` is augmented |
|
// to use "hex" encoding by default. This ensures bytewise encoding still |
|
// works when bytewise keys are accidentally coerced to strings. |
|
assert.equal(encode(-12345) + '', '41bf37e37fffffffff') |
|
|
|
// All numbers, integer or floating point, are stored as IEEE 754 doubles |
|
assert.equal(encode(1.2345) + '', '423ff3c083126e978d') |
|
assert.equal(encode(-1.2345) + '', '41c00c3f7ced916872') |
|
|
|
// Serialization does not preserve the sign bit, so 0 is indistinguishable from -0 |
|
assert.equal(encode(-0) + '', '420000000000000000') |
|
assert.equal(encode(0) + '', '420000000000000000') |
|
|
|
// Strings are encoded as utf8, prefixed with their type tag (0x70, or the "p" character) |
|
assert.equal(encode('foo').toString('utf8'), 'pfoo') |
|
assert.equal(encode('föo').toString('utf8'), 'pföo') |
|
|
|
// Arrays are just a series of values, separated by and terminated with a null byte |
|
assert.equal(encode([ 'foo', 'bar' ]) + '', 'a070666f6f00706261720000') |
|
|
|
// Items in arrays are delimited by null bytes, and a final end byte marks the end of the array |
|
assert.equal(encode([ 'foo' ]).toString('binary'), '\xa0pfoo\x00\x00') |
|
|
|
// Complex types like arrays can be arbitrarily nested, and fixed-sized types don't require a terminating byte |
|
assert.equal(encode([ [ 'foo', 10 ], 'bar' ]) + '', 'a0a070666f6f0042402400000000000000706261720000') |
|
``` |
|
|
|
|
|
`decode` parses a buffer and returns the structured data. |
|
|
|
```js |
|
var decode = bytewise.decode |
|
var key = 'a0a070666f6f0042402400000000000000706261720000' |
|
|
|
// Decode takes a buffer and decodes a bytewise value |
|
assert.deepEqual(decode(new Buffer(key, 'hex')), [ [ 'foo', 10 ], 'bar' ]) |
|
|
|
// String input can be decoded, defaulting to hex |
|
assert.deepEqual(decode(key), [ [ 'foo', 10 ], 'bar' ]) |
|
|
|
// An alternate string encoding can be provided when initializing bytewise |
|
// TODO |
|
``` |
|
|
|
|
|
## Use Cases |
|
|
|
Take a look at the [bytewise](https://github.com/deanlandolt/bytewise#use-cases) library for an idea of what kind of stuff this could be useful for. |
|
|
|
|
|
## Issues |
|
|
|
Issues should be reported [here](https://github.com/deanlandolt/bytewise/issues). |
|
|
|
|
|
## License |
|
|
|
[MIT](http://deanlandolt.mit-license.org/)
|
|
|