Comparing version 3.3.0 to 3.3.1
@@ -51,3 +51,3 @@ const Put = require('./put') | ||
if (this._condition) this._condition(node.value, oncondition) | ||
if (this._condition) this._condition(node, oncondition) | ||
else del() | ||
@@ -54,0 +54,0 @@ |
@@ -16,2 +16,3 @@ const Node = require('./node') | ||
this._finalized = false | ||
this._head = null | ||
@@ -36,3 +37,3 @@ if (this._batch) this._update(0, this._batch.head()) | ||
function onhead (err, head) { | ||
if (err) return self._finalize(err, null) | ||
if (err) return self._finalize(err) | ||
self._update(0, head) | ||
@@ -42,3 +43,3 @@ } | ||
Put.prototype._finalize = function (err, lastNode) { | ||
Put.prototype._finalize = function (err) { | ||
const self = this | ||
@@ -55,3 +56,4 @@ | ||
if (this._condition) this._condition(lastNode, this._node, oncondition) | ||
if (this._head && this._head.key !== this._node.key) this._head = null | ||
if (this._condition) this._condition(this._head, this._node, oncondition) | ||
else insert() | ||
@@ -137,3 +139,5 @@ | ||
this._finalize(null, head) | ||
this._head = head | ||
this._finalize(null) | ||
} | ||
@@ -140,0 +144,0 @@ |
{ | ||
"name": "hypertrie", | ||
"version": "3.3.0", | ||
"version": "3.3.1", | ||
"description": "Distributed single writer key/value store", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -46,10 +46,30 @@ # hypertrie | ||
#### `db.put(key, value, [callback])` | ||
#### `db.put(key, value, [options], [callback])` | ||
Insert a value | ||
Insert a value. | ||
#### `db.del(key, [callback])` | ||
Options can include: | ||
``` | ||
{ | ||
condition: function (oldNode, newNode, cb(err, bool)) { ... } | ||
} | ||
``` | ||
The optional `condition` function provides atomic compare-and-swap semantics, allowing you to optionally abort a put based on the current and intended node values. | ||
The condition callback should be used as follows: | ||
1. `cb(new Error(...))`: Abort with an error that will be forwarded through the `put`. | ||
2. `cb(null, false)`: Abort the put, but do not produce an error. | ||
3. `cb(null, true)`: Proceed with the put. | ||
#### `db.del(key, [options], [callback])` | ||
Delete a key from the database. | ||
Options can include: | ||
``` | ||
{ | ||
condition: function (oldNode, cb(err, bool)) { ... } | ||
} | ||
``` | ||
The optional `condition` function behaves the same as the one in `put`, minus the `newNode` parameter. | ||
#### `db.batch(batch, [callback])` | ||
@@ -56,0 +76,0 @@ |
@@ -41,2 +41,58 @@ const tape = require('tape') | ||
tape('condition: put only if value is null, nested paths', function (t) { | ||
const db = create() | ||
db.put('/a/b', 'world', { condition: onlyIfNull }, err => { | ||
t.error(err, 'no error') | ||
db.put('/a/b/c', 'friend', { condition: onlyIfNull }, err => { | ||
t.error(err, 'no error') | ||
t.same(db.version, 3) | ||
t.end() | ||
}) | ||
}) | ||
function onlyIfNull (oldNode, newNode, cb) { | ||
if (!newNode) return cb(new Error('Cannot insert a null value (use delete)')) | ||
if (oldNode) return cb(null, false) | ||
return cb(null, true) | ||
} | ||
}) | ||
tape('condition: two keys with same siphash', function (t) { | ||
const db = create() | ||
var pending = 2 | ||
db.put('idgcmnmna', 'a', function () { | ||
db.put('mpomeiehc', 'b', { condition: onlyIfNull }, function (err) { | ||
t.error(err, 'no error') | ||
t.same(db.version, 3) | ||
testKey('idgcmnmna', ifValueMatches('a')) | ||
testKey('mpomeiehc', ifValueMatches('b')) | ||
}) | ||
}) | ||
function testKey (key, condition) { | ||
db.put(key, 'c', { condition }, function (err) { | ||
t.error(err, 'no error') | ||
db.get(key, function (err, node) { | ||
t.error(err, 'no error') | ||
t.same(node.value, 'c') | ||
if (!--pending) return t.end() | ||
}) | ||
}) | ||
} | ||
function ifValueMatches (val) { | ||
return function (oldNode, newNode, cb) { | ||
if (oldNode && oldNode.value === val) return cb(null, true) | ||
return cb(null, false) | ||
} | ||
} | ||
function onlyIfNull (oldNode, newNode, cb) { | ||
if (!newNode) return cb(new Error('Cannot insert a null value (use delete)')) | ||
if (oldNode) return cb(null, false) | ||
return cb(null, true) | ||
} | ||
}) | ||
tape('condition: delete only a certain value', function (t) { | ||
@@ -61,3 +117,3 @@ const db = create() | ||
t.error(err, 'no error') | ||
t.same(node, null) | ||
t.true(node === null) | ||
t.end() | ||
@@ -70,3 +126,3 @@ }) | ||
return function (node, cb) { | ||
if (node === value) return cb(null, true) | ||
if (node && node.value === value) return cb(null, true) | ||
return cb(null, false) | ||
@@ -73,0 +129,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
83667
2616
213